library(tidyverse)
library(Rlab)
library(BSDA)

#Discrete ##UNIFORM ###Population ####1. Model

m_ <- 1
n <- 7
range <- m_:n
mean <- (n+m_)/2
variance <- ((n-m_)*(n-m_+2))/12
print(str_c("m = ", m_, ", n = ", n, ", mean = ", mean, ", variance = ", variance))
[1] "m = 1, n = 7, mean = 4, variance = 4"
rdunif(10, n, m_)
 [1] 1 5 4 2 7 6 2 4 4 1
dunif <- tibble(x = range, d = 1/(n-m_+1), p = (x-m_+1)/(n-m_+1),
                xd = x*d)
dunif
ggplot(dunif) + geom_point(aes(x = x, y = p))

ggplot(dunif) + geom_point(aes(x = x, y = d))

##BERNOULLI ###Population ####1. Model

#Parameters
p <- 0.001 #right-skew for p <0.5, symmetric for p = 0.5, left-skew for p >0.5
str_c("p = ", p)
[1] "p = 0.001"
p_2 <- 0.8

#Range
range <- 0:1
#p.m.f.
dber <- function(x, p){
        p^x*(1-p)^(1-x)  #special case of binomial, where n_ = 1
}
bernoulli <- tibble(x = range,
                d = dber(x, p),
                p = pbern(x, p))
bernoulli
ggplot(bernoulli) + geom_point(aes(x = x, y = p))

ggplot(bernoulli) + geom_point(aes(x = x, y = d))

####2. Expected values

mu <- p
sigma_squared <- p*(1-p)
sigma <- sqrt(sigma_squared)

# x <- bernoulli$x
# m <- bernoulli$m
#mu <- sum(x*m)
#sigma_squared <- sum((x-mu)^2*m)
#sigma_squared <- sum(x^2*m)-mu^2 

str_c("mu = ", mu, ", sigma_squared = ", sigma_squared, ", sigma = ", round(sigma,2))
[1] "mu = 0.001, sigma_squared = 0.000999, sigma = 0.03"

####3. Sampling distribution of the sample mean, expected values

#range: 0-1
n <- 5000
exp_X_bar <- mu #p
var_X_bar <- sigma_squared/n #p(1-p)/n
sd_X_bar <- sqrt(var_X_bar) #sqrt(p(1-p)/n)
        
#if X ~ binom(n,p), E(X) = np, V(X) = np(1-p)
# E(X/n) = E(X)/n = p
# V(X/n) = V(X)/n^2 = np(1-p)/n^2 = p(1-p)/n
# S(X/n) = sqrt(p(1-p)/n)
# X/n ≈ N(p, p(1-p)/n), when both np and n(1-p) ≥ 5

str_c("n = ", n, ", exp_X_bar = ", exp_X_bar, ", var_X_bar = ", round(var_X_bar,3), ", sd_X_bar = ", round(sd_X_bar,3), ", n*p = ", n*p,  ", n*(1-p) = ", n*(1-p))
[1] "n = 5000, exp_X_bar = 0.001, var_X_bar = 0, sd_X_bar = 0, n*p = 5, n*(1-p) = 4995"

###Sample

x <- rbern(n, p) #a single observation of binomial random variable is n observations of a Bernoulli random variable
n_2 <- 60
x_2 <- rbern(n_2, p_2)

####a. Estimates

sample_mean <- mean(x) #p_hat, sample_total/n, (binomial x/n)
sample_total <- sum(x) #(x binomial)
est_var_X_bar <- (sample_mean*(1-sample_mean))/n #estimate sigma squared with sample_mean
est_sd_X_bar <- sqrt((sample_mean*(1-sample_mean))/n)

sample_mean_2 <- mean(x_2)
est_var_X_bar_2 <- (sample_mean_2*(1-sample_mean_2))/n_2 #estimate sigma squared with sample_mean
ext_var_X_bar_diff <- est_var_X_bar + est_var_X_bar_2
est_sd_X_bar_diff <- sqrt(ext_var_X_bar_diff)
sample_mean_diff <- sample_mean-sample_mean_2

#Sample variance notes
# sample_var <- sample_mean*(1-sample_mean) #p_hat(1-p_hat), biased estimator of S_squared?
# sample_sd <- sqrt(sample_var)
# sample_var2 <- var(x) #sample variance
# sample_sd2 <- sqrt(sample_var)
# sample_var3 <- sum((x-mean(x))^2)/length(x) #same as 1, biased?
# sample_sd3 <- sqrt(sample_var3)

str_c("sample_total = ", sample_total, ", sample_mean = ", sample_mean, ", est_var_X_bar = ", round(est_var_X_bar, 3), ", est_sd_X_bar = ", round(est_sd_X_bar, 3))
[1] "sample_total = 9, sample_mean = 0.0018, est_var_X_bar = 0, est_sd_X_bar = 0.001"

####b. Likelhood

#MLE: 
bernoullin_mle <- tibble(theta = seq(0,1,0.001),
                    m = dbinom(sum(x), n, p = theta)) #single observation of binomial
ggplot(bernoullin_mle) + geom_line(aes(x = theta, y = m))

####c.i. Confidence interval

alpha <- 0.05

#Confidence interval
CI <- c(sample_mean - qnorm(1-alpha/2)*est_sd_X_bar, 
        sample_mean + qnorm(1-alpha/2)*est_sd_X_bar)
str_c("sample_mean = ", sample_mean, ", CI = ", paste(round(CI,3), collapse = ", "))
[1] "sample_mean = 0.0018, CI = 0.001, 0.003"

####c.ii. Confidence interval difference of proportions

CI <- c(sample_mean_diff - qnorm(1-alpha/2)*est_sd_X_bar_diff, 
        sample_mean_diff + qnorm(1-alpha/2)*est_sd_X_bar_diff)
str_c("sample_mean_diff = ", round(sample_mean_diff,3), ", CI = ", paste(round(CI,3), collapse = ", "))
[1] "sample_mean_diff = -0.948, CI = -1.003, -0.893"

####d. Hypothesis test

alpha <- 0.05
p_0 = 0.3
critical_values <- c(p_0 - qnorm(1-alpha/2)*(sqrt(p_0*(1-p_0)/n)),
                     p_0 + qnorm(1-alpha/2)*(sqrt(p_0*(1-p_0)/n))) #not p_hat?
z <- ((sample_mean-p_0))/(sqrt(p_0*(1-p_0)/n))
standard_critical_values <- c(qnorm(alpha/2), qnorm(1-alpha/2))

p_value <- 2*(1-pnorm(abs(z)))
str_c("H0: p_0 = ", p_0)
[1] "H0: p_0 = 0.3"
str_c("critical values = ", paste(round(critical_values,3),collapse = ", "))
[1] "critical values = 0.287, 0.313"
str_c("sample_mean = ", round(sample_mean,3))
[1] "sample_mean = 0.002"
str_c("standard critical values = ", paste(round(standard_critical_values,3),collapse = ", "))
[1] "standard critical values = -1.96, 1.96"
str_c("z = ", round(z, 3))
[1] "z = -46.013"
str_c("p_value = ", round(p_value, 5))
[1] "p_value = 0"
prop.test(sample_total, n, p_0, correct = FALSE) #CI slightly different??

    1-sample proportions test without continuity correction

data:  sample_total out of n, null probability p_0
X-squared = 2117.2, df = 1, p-value < 2.2e-16
alternative hypothesis: true p is not equal to 0.3
95 percent confidence interval:
 0.0009472935 0.0034176447
sample estimates:
     p 
0.0018 

##BINOMIAL ###Population ####1. Model

#number of successes in a sequence of n independent Bernoulli trials with probability p
n_ <- 3000 #finite range, Bernoulli if n = 1
p <- 12/3000
# p <- l/n_ 
#right-skew for p <0.5, symmetric for p = 0.5, left-skew for p >0.5
#The Poisson distribution is the limiting distribution of X ~ B(n, l/n)
#If n is large and p is small (n ≥ 50 and p ≤ 0.05) then the binomial random variable B(n,p) has approximately the same distribution as Poisson(np)

# range <- 0:n_
range <- 0:50

db <- function(x, n_, p){
        choose(n_, x)*p^x*(1-p)^(n_-x)
}
binom <- tibble(x = range,
                d = db(x, n_, p), #one mode, can take any value, depends on p
                p = pbinom(x, n_, p))
binom
ggplot(binom) + geom_point(aes(x = x, y = p))

ggplot(binom) + geom_point(aes(x = x, y = d))

####2. Expected values

x <- binom$x
d <- binom$d
mu <- n_*p #linear, ranges from 0 < mean < n
#mu <- sum(x*m)
sigma_squared <- n_*p*(1-p) #quadratic, max 0.25n, var -> mean as p -> 0, mean - var -> n as p -> 1
#sigma_squared <- sum((x-mu)^2*m)
#sigma_squared <- sum(x^2*m)-mu^2 
sigma <- sqrt(sigma_squared)
str_c("mu (np) = ", mu, ", sigma_squared (np(1-p)) = ", sigma_squared, ", sigma = ", round(sigma,2))
[1] "mu (np) = 12, sigma_squared (np(1-p)) = 11.952, sigma = 3.46"

####3. Sampling distributions of the sample mean, expected values

n <- 50
exp_X_bar <- mu
var_X_bar <- sigma_squared/n #p*(1-p) (same as sigma_squared Bernoulli)
sd_X_bar <- sqrt(var_X_bar)

str_c("n = ", n, ", exp_X_bar = ", exp_X_bar, ", var_X_bar = ", round(var_X_bar,3), ", sd_X_bar = ", round(sd_X_bar,3))
[1] "n = 50, exp_X_bar = 12, var_X_bar = 0.239, sd_X_bar = 0.489"

##POISSON ###Population ####1. Model

#The Poisson distribution is the limiting distribution of X ~ B(n, l/n)
#If n is large and p is small (n ≥ 50 and p ≤ 0.05) then the binomial random variable B(n,p) has approximately the same distribution as Poisson(np)
#For a Poisson process in which events occur at random at rate l, the number of events that occur during a time interval of length t has a Poisson distribution with parameter lt
l <- 0.1 #constant event rate
t <- 100 #time interval
lt <- l*t #decreasing p.m.f. when lt < 1
str_c("rate = ", l, ", time = ", t, ", lt = ", lt)
[1] "rate = 0.1, time = 100, lt = 10"
#Range
range <- 0:50 #unbounded to the right
#p.d.f
dp <- function(x, lt){
        (exp(1)^(-lt)*lt^x)/factorial(x)
}
poisson <- tibble(x = range,
                d = dp(x, lt), #one mode, can take any value
                p = ppois(x, lt))
poisson
ggplot(poisson) + geom_point(aes(x = x, y = p))

ggplot(poisson) + geom_point(aes(x = x, y = d))

####2. Expected values

#Mu, sigma
mu <- lt
sigma_squared <- lt
sigma <- sqrt(sigma_squared)

str_c("mu = ", mu, ", sigma_squared = ", sigma_squared, ", sigma = ", round(sigma,3))
[1] "mu = 10, sigma_squared = 10, sigma = 3.162"

####3. Sampling distribution of the sample mean, expected values

n <- 1000
exp_X_bar <- mu
var_X_bar <- sigma_squared/n
sd_X_bar <- sqrt(var_X_bar)
str_c("n = ", n, ", exp_X_bar = ", exp_X_bar, ", var_X_bar = ", round(var_X_bar,3), ", sd_X_bar = ", round(sd_X_bar,3))
[1] "n = 1000, exp_X_bar = 10, var_X_bar = 0.01, sd_X_bar = 0.1"

[1] “n = 1000, exp_X_bar = 0.1, var_X_bar = 0, sd_X_bar = 0.01”

[1] “n = 100, exp_X_bar = 1, var_X_bar = 0.01, sd_X_bar = 0.1”

[1] “n = 10, exp_X_bar = 10, var_X_bar = 1, sd_X_bar = 1”

###Sample

x <- rpois(n, lt)

# O <- c(21,8,6,1)
# n <- sum(O)
# range <- 0:(length(O)-1)
# x <- rep(range, O)

#E.coli
#x <- c(3274,3198,3258,3276,3456,3384,3280,3081,3062,3023,3073,2794,3068)

####a. Estimates

str_c("lt = ", lt) #can use normal approximation when lt >= 30
[1] "lt = 10"
sample_mean <- mean(x) #l_hat

est_var_X_bar <- sample_mean/n #estimate sigma squared with sample_mean
est_sd_X_bar <- sqrt(sample_mean/n)

str_c("sample_mean (l_hat) = ", round(sample_mean,3), ", est_var_X_bar = ", round(est_var_X_bar,3), ", est_sd_X_bar = ", round(est_sd_X_bar,3))
[1] "sample_mean (l_hat) = 9.951, est_var_X_bar = 0.01, est_sd_X_bar = 0.1"

####b. Likelhood

theta <- seq(0,max(range), max(range)/1000)
lp <- function(x, theta){
        n <- length(x)
        c <- 1/prod(factorial(x))
        sample_mean <- mean(x)
        c*exp(1)^(-n*theta)*theta^(n*sample_mean)
}
poisson_mle <- tibble(theta = theta, m = lp(x, theta))
ggplot(poisson_mle) + geom_line(aes(x = theta, y = m))

####c. Confidence interval

alpha <- 0.05
str_c("alpha = ", alpha)
[1] "alpha = 0.05"
#Confidence interval
CI <- c(sample_mean - qnorm(1-alpha/2)*est_sd_X_bar, 
        sample_mean + qnorm(1-alpha/2)*est_sd_X_bar)
str_c("CI = ", paste(round(CI,3), collapse = ", "))
[1] "CI = 9.755, 10.147"

“CI = 0.059, 0.093” CI*100 = 5.9 9.3

“CI = 0.732, 1.108” CI*10 = 7.32 11.08

“CI = 6.693, 10.307”

##GEOMETRIC ###Population ####1. Model

p <- 0.8
str_c("p = ", p)
[1] "p = 0.8"
range <- 1:10 #1,2,3,..., unbounded to the right
#p.m.f.
dg <- function(x, p){
        ((1-p)^(x-1))*p
}
#c.d.f.
pg <- function(x, p){
        1-(1-p)^x
}
geom <- tibble(x = range, 
                d = dg(x, p), #decreasing p.m.f., mode always at 1 
                p = pg(x, p))
geom
ggplot(geom) + geom_point(aes(x = x, y = p))

ggplot(geom) + geom_point(aes(x = x, y = d))

####2. Expected values

#Mu, sigma
mu <- 1/p #mean < variance for p < 0.5, mean > variance for p > 0.5
sigma_squared <- (1-p)/p^2
sigma <- sqrt(sigma_squared)
str_c("mu = ", mu, ", sigma_squared = ", sigma_squared, ", sigma = ", sigma)
[1] "mu = 1.25, sigma_squared = 0.3125, sigma = 0.559016994374947"

###Sample

x <- rgeom(100, p) + 1 #shifted geometric distribution

####a. Estimates

sample_mean <- mean(x)
p_hat <- 1/sample_mean #biased

str_c('sample_mean = ', round(sample_mean,2), ", p_hat = ", round(p_hat,2))
[1] "sample_mean = 1.24, p_hat = 0.81"

####b. Likelhood

theta <- seq(0,1,0.001)
lg <- function(x, theta){
        n <- length(x)
        (1-theta)^(sum(x)-n)*theta^n
}
geom_mle <- tibble(theta = theta, m = lg(x, theta))
ggplot(geom_mle) + geom_line(aes(x = theta, y = m))

##NEGATIVE BINOMIAL ###Population ####1. Model

r <- 5
p <- 0.5
str_c("p = ", p, ", r = ", r)
[1] "p = 0.5, r = 5"
range <- 0:50 #1,2,3,..., unbounded to the right
#p.m.f.
#c.d.f.

nb <- tibble(x = range, 
                d = dnbinom(x, r, p), 
                p = pnbinom(x, r, p))
nb
ggplot(nb) + geom_point(aes(x = x, y = p))

ggplot(nb) + geom_point(aes(x = x, y = d))

#Continuous ##UNIFORM ###Population ####1. Model

a <- 1
b <- 5
mean <- (a+b)/2
variance <- (b-a)^2/12
range <- c(a,b)
print(str_c("a = ", a, ", b = ", b, ", mean = ", mean, ", variance = ", variance))
[1] "a = 1, b = 5, mean = 3, variance = 1.33333333333333"
unif <- tibble(x = range, d = 1/(b-a), p = (x-a)/(b-a))
unif
ggplot(unif) + geom_line(aes(x = x, y = p))

ggplot(unif) + geom_line(aes(x = x, y = d))

###Sample

x <- runif(10, a, b)

##EXPONENTIAL ###Population ####1. Model

#For a Poisson process win which events occur at random at rate l, the waiting time between successive events has an exponential distribution with parameter l
#Parameters
l <- 1/26 #rate
range <- seq(0.0001, 100, 100/1000) # X > 0, unbounded to the right
str_c("lambda = ", l)
[1] "lambda = 0.0384615384615385"
#p.d.f.
de <- function(x, l){
      l*exp(1)^(-l*x) #decreasing p.d.f.  
}

#c.d.f.
pe <- function(x, l){
        p = 1-exp(1)^(-l*x)
}

exponential <- tibble(x = range, 
                d = de(x, l),
                p = pe(x, l))
exponential
ggplot(exponential) + geom_line(aes(x = x, y = p))

ggplot(exponential) + geom_line(aes(x = x, y = d))

####2. Expected values

#Mu, sigma
mu <- 1/l
sigma_squared <- 1/l^2
sigma <- sqrt(sigma_squared) #mu = sigma

str_c("mu = ", mu, ", sigma_squared = ", sigma_squared, ", sigma = ", sigma)
[1] "mu = 26, sigma_squared = 676, sigma = 26"

###Sample

x <- rexp(10, l)

####a. Estimates

sample_mean <- mean(x)
l_hat = 1/sample_mean #biased

####b. Likelhood

theta <- seq(0,3*l, 3*l/1000)

str_c('sample_mean = ', round(sample_mean,2), ", l_hat = ", round(l_hat,2))
[1] "sample_mean = 22.45, l_hat = 0.04"
le <- function(x, theta){
        n <- length(x)
        sample_mean <- mean(x)
        (theta^n)*exp(1)^(-theta*n*sample_mean)
}
exponential_mle <- tibble(theta = theta, m = le(x, theta))
ggplot(exponential_mle) + geom_line(aes(x = theta, y = m))

##NORMAL ###Population ####1. Model

#Parameters
mu <- 7
sigma_squared <- 100
sigma <- sqrt(sigma_squared)
str_c("mu = ", mu, ", sigma_squared = ", sigma_squared, ", sigma = ", sigma)
[1] "mu = 7, sigma_squared = 100, sigma = 10"
mu_2 <- 9

#Range
range <- seq(mu-4*sigma, mu+4*sigma, sigma/12) #unbounded 

#p.d.f.
dn <- function(x, mu, sigma){
        (1/(sigma*sqrt(2*pi)))*exp(-0.5*((x-mu)/sigma)^2)
}
normal <- tibble(x = range,
                 d = dn(x, mu, sigma), #symmetric about mean
                 p = pnorm(x, mu, sigma))
normal
ggplot(normal) + geom_line(aes(x = x, y = p))

ggplot(normal) + geom_line(aes(x = x, y = d))

####2. Expected values

str_c("mu = ", mu, ", sigma_squared = ", sigma_squared, ", sigma = ", round(sigma,3))
[1] "mu = 7, sigma_squared = 100, sigma = 10"

####3. Sampling distributions of the sample mean, expected values

n <- 20

exp_X_bar <- mu
var_X_bar <- sigma_squared/n
sd_X_bar <- sigma/sqrt(n)
str_c("n = ", n, ", exp_X_bar = ", round(exp_X_bar,3), ", var_X_bar = ", round(var_X_bar,3), ", sd_X_bar = ", round(sd_X_bar,3))
[1] "n = 20, exp_X_bar = 7, var_X_bar = 5, sd_X_bar = 2.236"

####4. Sampling distribution of the sample variance, expected values

exp_S_squared <- sigma_squared
exp_S <- sigma
str_c("exp_S_squared = ", round(exp_S_squared,3), ", exp_S = ", round(exp_S,3))
[1] "exp_S_squared = 100, exp_S = 10"

###Sample

x <- rnorm(n, mu, sigma)

n_2 <- 30
x_2 <- rnorm(n, mu_2, sigma)
# x <- c(-6,1,2,4,24,27,33)
# n <- length(x)

####a. Estimates

sample_mean <- mean(x) #mu_hat

sample_var <- var(x) #s_squared
sample_sd <- sqrt(sample_var) #s

sample_mean_2 <- mean(x_2)
sample_var_2 <- var(x_2)
sample_var_pooled <- ((n-1)*sample_var+(n_2-1)*sample_var_2)/(n+n_2-2)
sample_sd_pooled <- sqrt(sample_var_pooled)
sample_mean_diff <- sample_mean-sample_mean_2

# sigma_squared_hat <- sum((x-mean(x))^2)/length(x) #biased
# sigma_hat <- sqrt(sum((x-mean(x))^2)/length(x)) #biased

est_var_X_bar <- sample_var/n #estimate sigma_squared with sample_var
est_sd_X_bar <- sample_sd/sqrt(n) #estimate sigma with sample_sd

str_c("sample_mean = ", round(sample_mean,3), ", sample_var = ", round(sample_var,3), ", sample_sd = ", round(sample_sd,3), ", est_var_X_bar = ", round(est_var_X_bar,3), ", est_sd_X_bar = ", round(est_sd_X_bar,3))
[1] "sample_mean = 8.025, sample_var = 117.105, sample_sd = 10.821, est_var_X_bar = 5.855, est_sd_X_bar = 2.42"

####c. Confidence interval

alpha <- 0.05
str_c("alpha = ", alpha)
[1] "alpha = 0.05"
#Confidence interval
CI <- c(sample_mean - qnorm(1-alpha/2)*est_sd_X_bar, 
        sample_mean + qnorm(1-alpha/2)*est_sd_X_bar)
str_c("CI = ", paste(round(CI,3), collapse = ", "))
[1] "CI = 3.282, 12.767"

####d. Hypothesis test

mu_0 = 7
critical_values <- c(mu_0 - qnorm(1-alpha/2)*est_sd_X_bar,
                     mu_0 + qnorm(1-alpha/2)*est_sd_X_bar)
z <- (sample_mean-mu_0)/est_sd_X_bar #when H_0 is true, Z ~ N(0,1)
standard_critical_values <- c(qnorm(alpha/2), qnorm(1-alpha/2))
p_value <- 2*(1-pnorm(abs(z)))

str_c("H0: mu_0 = ", mu_0)
[1] "H0: mu_0 = 7"
str_c("critical values = ", paste(round(critical_values,3),collapse = ", "))
[1] "critical values = 2.257, 11.743"
str_c("sample_mean = ", round(sample_mean,3))
[1] "sample_mean = 8.025"
str_c("standard critical values = ", paste(round(standard_critical_values,3),collapse = ", "))
[1] "standard critical values = -1.96, 1.96"
str_c("z = ", round(z, 3))
[1] "z = 0.423"
str_c("p_value = ", round(p_value, 5))
[1] "p_value = 0.67193"
z.test(x, mu = mu_0, sigma.x = sample_sd)

    One-sample z-Test

data:  x
z = 0.4235, p-value = 0.6719
alternative hypothesis: true mean is not equal to 7
95 percent confidence interval:
  3.282115 12.767398
sample estimates:
mean of x 
 8.024757 

####e. Power and sample size

#When H_1 is true, mu = mu_0 + d, Z - d/sd_X_bar ~ N(0,1)
d <-  2
sigma <- 5
n <- 30
sd_X_bar <- sigma/sqrt(n)
alpha <- 0.05
d_z <- d/sd_X_bar
power <- 1 - pnorm(qnorm(1-alpha/2) - d_z)
str_c("d = ", d, ", d_z = ", round(d_z,3),  ", power = ", round(power,4))
[1] "d = 2, d_z = 2.191, power = 0.5913"

####f. Sample size

gamma <- 0.9
sample_size <- (sigma_squared/d^2)*(qnorm(1-alpha/2) - qnorm(1-gamma))^2

str_c("d = ", d,  ", gamma = ", gamma, ", sample size = ", ceiling(sample_size))
[1] "d = 2, gamma = 0.9, sample size = 263"

##STUDENT’S T ###Population ####1. Model

nu <- n-1
range <- seq(-4, 4, 0.08) #unbounded 
print(str_c("df = ", nu))
[1] "df = 29"
rt(10, nu)
 [1]  1.67735680  1.12206592  0.04699416  0.47174787 -1.41414352  0.55495910 -0.90380532 -0.94227759
 [9]  0.74383999 -0.45816169
t <- tibble(x = range, 
                d = dt(x, nu),
                p = pt(x, nu))
t
ggplot(t) + geom_line(aes(x = x, y = p))

ggplot(t) + geom_line(aes(x = x, y = d))

###Sample Use normal

####c.i. Confidence interval

alpha <- 0.05
str_c("alpha = ", alpha)
[1] "alpha = 0.05"
#Confidence interval
CI <- c(sample_mean - qt(1-alpha/2, nu)*est_sd_X_bar, 
        sample_mean + qt(1-alpha/2, nu)*est_sd_X_bar)
str_c("CI = ", paste(round(CI,6), collapse = ", "))
[1] "CI = 3.075793, 12.973721"

####c.ii Confidence interval for difference of means

nu_2 <- n + n_2 - 2

CI <- c(sample_mean_diff - qt(1-alpha/2, nu_2)*sample_sd_pooled*sqrt(1/n+1/n_2), 
        sample_mean_diff + qt(1-alpha/2, nu_2)*sample_sd_pooled*sqrt(1/n+1/n_2))

str_c("CI = ", paste(round(CI,6), collapse = ", "))
[1] "CI = -5.161838, 5.561424"

####d. Hypothesis test

mu_0 = 0
critical_values <- c(mu_0 - qt(1-alpha/2, nu)*est_sd_X_bar,
                     mu_0 + qt(1-alpha/2, nu)*est_sd_X_bar)
t <- (sample_mean-mu_0)/est_sd_X_bar
standard_critical_values <- c(qt(alpha/2, nu), qt(1-alpha/2, nu))

p_value <- 2*(1-pt(abs(t), nu))
str_c("H0: mu_0 = ", mu_0)
[1] "H0: mu_0 = 0"
str_c("df = ", length(x)-1)
[1] "df = 19"
str_c("critical values = ", paste(round(critical_values,3),collapse = ", "))
[1] "critical values = -4.949, 4.949"
str_c("sample_mean = ", round(sample_mean,3))
[1] "sample_mean = 8.025"
str_c("standard critical values = ", paste(round(standard_critical_values,3),collapse = ", "))
[1] "standard critical values = -2.045, 2.045"
str_c("t = ", round(t, 4))
[1] "t = 3.3163"
str_c("p_value = ", round(p_value, 5))
[1] "p_value = 0.00246"
t.test(x, mu = mu_0, sigma.x = sample_sd)

    One Sample t-test

data:  x
t = 3.3163, df = 19, p-value = 0.003629
alternative hypothesis: true mean is not equal to 0
95 percent confidence interval:
  2.960142 13.089372
sample estimates:
mean of x 
 8.024757 

##CHI-SQUARED

r <- 6
range <- seq(0.0001, 5*r, r/20) #x > 0
print(str_c("degrees of freedom = ", r, ", mean = ", r, ", variance = ", 2*r))
[1] "degrees of freedom = 6, mean = 6, variance = 12"
rchisq(10, r)
 [1] 19.912654  2.424535 15.085342  8.567419  6.483809  7.789849 12.606974 11.472406  6.432920
[10] 10.010097
chisq <- tibble(x = range, 
                d = dchisq(x, r),
                p = pchisq(x, r))
chisq
ggplot(chisq) + geom_line(aes(x = x, y = p))

ggplot(chisq) + geom_line(aes(x = x, y = d))

###Goodness of fit ####discrete uniform

m_ <- 1
n <- 7
O <- c(17,10,12,15,5,4,8)
n <- sum(O)
x <- 1:length(O)
m <- 1/(n-m_+1)
gof <- tibble(x = x,
                m = m,
                O = O, 
                E = m*n,
                '(O-E)^2/E' = (O-E)^2/E)
gof
x2 <- sum(gof$`(O-E)^2/E`)
n_parameters <- 0
r <- nrow(gof) - n_parameters - 1 #k - p - 1
str_c("n = ", n, ", chi_square = ", round(x2,3), ", p = ", round(1-pchisq(x2, r),3))
[1] "n = 71, chi_square = 728, p = 0"

####geometric

p_hat <- 0.657
O <- c(71,28,10)
n <- sum(O)
x <- 1:(length(O)-1)
y <- str_c("≥", (length(O)))
m <- c(dg(x, p_hat),1-pg(max(x), p_hat))
gof <- tibble(x = c(x,y),
                m = m,
                O = O, 
                E = m*n,
                '(O-E)^2/E' = (O-E)^2/E)
gof
x2 <- sum(gof$`(O-E)^2/E`)
n_parameters <- 1
r <- nrow(gof) - n_parameters - 1 #k - p - 1
str_c("n = ", n, ", p_hat = ", p_hat, ", df = ", r, " , chi_square = ", round(x2,3), ", p = ", round(1-pchisq(x2, r),3))
[1] "n = 109, p_hat = 0.657, df = 1 , chi_square = 1.108, p = 0.293"

####Poisson

l_hat <- 0.7
O <- c(144,91,32,13)
n <- sum(O)
x <- 0:(length(O)-2)
y <- str_c("≥", (length(O)-1))
m <- c(dpois(x, l_hat),1-ppois(max(x), l_hat))
gof <- tibble(x = c(x,y),
                m = m,
                O = O, 
                E = m*n,
                '(O-E)^2/E' = (O-E)^2/E)
gof
x2 <- sum(gof$`(O-E)^2/E`)

n_parameters <- 1 #estimated from data
r <- nrow(gof) - n_parameters - 1 #k - p - 1

str_c("n = ", n, ", l_hat = ", l_hat, ", df = ", r, ", chi_square = ", round(x2,3), ", p = ", round(1-pchisq(x2, r),3))
[1] "n = 280, l_hat = 0.7, df = 2, chi_square = 1.952, p = 0.377"

##REGRESSION ###Population

#Parameters
sigma_squared <- 150
sigma <- sqrt(sigma_squared)
alpha_ <- 5
beta <- 4
x <- seq(-5,20,0.25)

h <- function(x, alpha_, beta){
        alpha_ + beta*x
}
#p.d.f.
regression_model <- tibble(x = x,
                 q_0.025 = qnorm(0.025, h(x, alpha_, beta), sigma),
                 q_0.5 = qnorm(0.5, h(x, alpha_, beta), sigma),
                 q_0.975 = qnorm(0.975, h(x, alpha_, beta), sigma)
                 ) %>%
        gather(key = quantile, value = z, -x)

regression_model
ggplot(regression_model) + geom_line(aes(x = x, y = z, col = quantile))

####Sampling distribution of the estimators, expected values

n <- 50

exp_alpha_hat <- alpha
exp_beta_hat <- beta

###Sample

regression_sample <- tibble(x = runif(n, min(x), max(x)),
                     y = rnorm(x, h(x, alpha_, beta), sigma))

ggplot(regression_sample) + geom_point(aes(x = x, y = y)) + expand_limits(x = 0, y = 0)

####a. Estimates

x <- regression_sample$x
x_bar <- mean(x)
y <- regression_sample$y

S_xx <- sum((x-mean(x))^2)
S_yy <- sum((y-mean(y))^2)
S_xy <- sum((x-mean(x))*(y-mean(y)))

#Least squares estimates of parameters
beta_hat <- S_xy/S_xx
#est_var_beta_hat <- sigma_squared/S_xx

alpha_hat <- mean(y) - beta_hat*mean(x)
#est_var_alpha_hat <- x_bar^2/S_xx+1/n

#Best fit
best_fit <- function(x, alpha_hat, beta_hat){
        alpha_hat + beta_hat*x
}

regression_sample <- regression_sample %>% 
        mutate(y_hat = best_fit(x, alpha_hat, beta_hat),
               residual = y-y_hat )

#Variance of residuals
y_hat <- regression_sample$y_hat
sum_squared_diff_y_hat <- sum((y-y_hat)^2)

s_squared <- sum_squared_diff_y_hat/(n-2) #unbiased estimator of sigma_squared, the variance of the random terms
s <- sqrt(s_squared)

est_sd_beta_hat <- s/sqrt(S_xx)

ggplot(regression_sample) + geom_point(aes(x = x, y = y)) + geom_line(aes(x = x, y = y_hat))

####c.i. Confidence interval for beta

alpha <- 0.05

CI_beta <- c(
        beta_hat - qt(1-alpha/2, n-2)*est_sd_beta_hat, 
        beta_hat + qt(1-alpha/2, n-2)*est_sd_beta_hat)

str_c("beta_hat = ", round(beta_hat,3), ", CI_beta = ", paste(round(CI_beta,3), collapse = ", "))
[1] "beta_hat = 3.791, CI_beta = 3.269, 4.313"

####c.ii. Confidence interval for mean response

est_sd_Y_bar <- function(x, s, x_bar, S_xx, n){
        s*sqrt((x-x_bar)^2/S_xx + 1/n)
}
        
regression_sample <- regression_sample %>% 
 mutate(CI_low = y_hat - qt(1-alpha/2, n-2)*est_sd_Y_bar(x, s, x_bar, S_xx, n),
        CI_high = y_hat + qt(1-alpha/2, n-2)*est_sd_Y_bar(x, s, x_bar, S_xx, n))

ggplot(regression_sample) + geom_point(aes(x = x, y = y)) + geom_line(aes(x = x, y = y_hat)) + geom_line(aes(x = x, y = CI_low)) + geom_line(aes(x = x, y = CI_high))

####c.iii. Prediction interval

est_sd_Y <- function(x, s, x_bar, S_xx, n){
        s*sqrt((x-x_bar)^2/S_xx + 1/n + 1)
}
        
regression_sample <- regression_sample %>% 
 mutate(CI_low = y_hat - qt(1-alpha/2, n-2)*est_sd_Y(x, s, x_bar, S_xx, n),
        CI_high = y_hat + qt(1-alpha/2, n-2)*est_sd_Y(x, s, x_bar, S_xx, n))

ggplot(regression_sample) + geom_point(aes(x = x, y = y)) + geom_line(aes(x = x, y = y_hat)) + geom_line(aes(x = x, y = CI_low)) + geom_line(aes(x = x, y = CI_high))

####d. Hypothesis test for beta

beta_0 = 0
critical_values <- c(beta_0 - qt(1-alpha/2, n-2)*est_sd_beta_hat,
                     beta_0 + qt(1-alpha/2, n-2)*est_sd_beta_hat)
t <- (beta_hat-beta_0)/est_sd_beta_hat
standard_critical_values <- c(qt(alpha/2, n-2), qt(1-alpha/2, n-2))

p_value <- 2*(1-pt(abs(t), n-2))

##NON-PARAMETRIC ###Wilkoxon signed rank

#Single sample
x <- c(19, 35, 36, 28, 37, 10, 25, 34, 30, 39)
m_0 = 35 #set hypothesized median
d_ <- x-m_0 #calculate difference

#set of paired differences
x1 <- c(171, 729, 679, 431, 300, 310, 794, 970, 388)
x2 <- c(198, 734, 779, 776, 300, 750, 697, 368, 488)
d_ <- x1-x2

d <- d_[d_!=0] #remove zeros
rank <- rank(abs(d)) #find the rank of absolute values
w_plus <- sum(rank[sign(d)==1]) #sum of the ranks of positive differences
w_plus
[1] 11
wilcox.test(d)

    Wilcoxon signed rank test with continuity correction

data:  d
V = 11, p-value = 0.3621
alternative hypothesis: true location is not equal to 0

Normal approximation

#normal approximation when n ≥ 16
n <- length(d)

exp_w_plus <- (n*(n+1))/4
var_w_plus <- (n*(n+1)*(2*n+1))/24
sd_w_plus <- sqrt(var_w_plus)

alpha <- 0.05
critical_values <- c(m_0 - qnorm(1-alpha/2)*sd_w_plus,
                     m_0 + qnorm(1-alpha/2)*sd_w_plus)
z <- (w_plus - exp_w_plus)/sd_w_plus
standard_critical_values <- c(qnorm(alpha/2), qnorm(1-alpha/2))
p_value <- 2*(1-pnorm(abs(z)))

str_c("n = ", n)
[1] "n = 8"
str_c("H0: m_0 = ", m_0)
[1] "H0: m_0 = 35"
str_c("critical values = ", paste(round(critical_values,3),collapse = ", "))
[1] "critical values = 21.003, 48.997"
str_c("exp_w_plus = ", exp_w_plus)
[1] "exp_w_plus = 18"
str_c("standard critical values = ", paste(round(standard_critical_values,3),collapse = ", "))
[1] "standard critical values = -1.96, 1.96"
str_c("z = ", round(z, 3))
[1] "z = -0.98"
str_c("p_value = ", round(p_value, 5))
[1] "p_value = 0.32699"

###Mann-Whitney

a = c(101,104,107,107,121,121,124,134,146) 
b = c(91,93,97,100,101,102,107,114,115,126,131)

u_a <- sum(rank(c(a,b))[1:length(a)])
u_a
[1] 117.5

Normal approximation

#normal approximation when each sample ≥ 8
n_a <- length(a)
n_b <- length(b)

exp_u_a <- (n_a*(n_a+n_b+1))/2
var_u_a <- (n_a*n_b*(n_a+n_b+1))/12
sd_u_a <- sqrt(var_u_a)

alpha <- 0.05
critical_values <- c(m_0 - qnorm(1-alpha/2)*sd_u_a,
                     m_0 + qnorm(1-alpha/2)*sd_u_a)
z <- (u_a - exp_u_a)/sd_u_a
standard_critical_values <- c(qnorm(alpha/2), qnorm(1-alpha/2))
p_value <- 2*(1-pnorm(abs(z)))

str_c("n_a = ", n_a, ", n_b = ", n_b)
[1] "n_a = 9, n_b = 11"
str_c("H0: m_0 = ", m_0)
[1] "H0: m_0 = 35"
str_c("critical values = ", paste(round(critical_values,3),collapse = ", "))
[1] "critical values = 9.202, 60.798"
str_c("exp_u_a = ", exp_u_a)
[1] "exp_u_a = 94.5"
str_c("standard critical values = ", paste(round(standard_critical_values,3),collapse = ", "))
[1] "standard critical values = -1.96, 1.96"
str_c("z = ", round(z, 3))
[1] "z = 1.747"
str_c("p_value = ", round(p_value, 5))
[1] "p_value = 0.08057"

##NOTES ##To do Non-linear regression models and transformations Chi-square goodness of fit test for binomial

###Normal probability plot

O <- c(33, 2, 24, 27, 4, 1, -6)
x <- sort(O)
n <- length(x)
i <- 1:n
p <- i/(n+1)
y <- qnorm(p)
qplot(x,y) + geom_smooth(method = "lm", se = FALSE)

###Central limit theorem

#n <- 10
n_trials <- 500
x <- c()
for (i in 1:n_trials) {
        x[i] <- mean(rbernoulli(n_trials,0.001))        
}

#ggplot() + stat_qq_line(aes(sample = x)) + stat_qq(aes(sample = x))
ggplot() + geom_histogram(aes(x = x), binwidth = 0.00002)

###Ladder of powers

df <- tibble(x = rnorm(10, 100, 10), y = x + rnorm(10, 0, 1))
df
ggplot(df) + geom_point(aes(x = x, y = y))

###Binomial vs Poisson

x <- binom %>% select(x, Binomial = d)
y <- poisson %>% select(x, Poisson = d) %>% left_join(x, by = "x")
z <- y %>% gather(key, value = d, -x)
ggplot(z) + geom_point(aes(x = x, y = d, col = key))

###Statistical tables

x <- 0:9/100
phi_table <- tibble(z = seq(0,4,0.1), 
       '0' = round(pnorm(z+x[1]),4),
       '1' = round(pnorm(z+x[2]),4),
       '2' = round(pnorm(z+x[3]),4),
       '3' = round(pnorm(z+x[4]),4),
       '4' = round(pnorm(z+x[5]),4),
       '5' = round(pnorm(z+x[6]),4),
       '6' = round(pnorm(z+x[7]),4),
       '7' = round(pnorm(z+x[8]),4),
       '8' = round(pnorm(z+x[9]),4),
       '9' = round(pnorm(z+x[10]),4)
       )
phi_table
qz_table <- tibble(a = seq(0.5,0.999,0.01), q_a = round(qnorm(a),3))
qz_table
qt_table <- tibble(df = 1:100, 
                   '0.90' = round(qt(0.9, df),3),
                   '0.95' = round(qt(0.95, df),3),
                   '0.975' = round(qt(0.975, df),3),
                   '0.99' = round(qt(0.99, df),3),
                   '0.995' = round(qt(0.995, df),3),
                   '0.999' = round(qt(0.999, df),3))
qt_table
chisq_table <- tibble(df = 1:100, 
                   '0.005' = round(qchisq(0.005, df),2),
                   '0.01' = round(qchisq(0.01, df),2),
                   '0.025' = round(qchisq(0.025, df),2),
                   '0.05' = round(qchisq(0.05, df),2),
                   '0.1' = round(qchisq(0.1, df),2),
                   '0.5' = round(qchisq(0.5, df),2),
                   '0.9' = round(qchisq(0.9, df),2),
                   '0.95' = round(qchisq(0.95, df),2),
                   '0.975' = round(qchisq(0.975, df),2),
                   '0.99' = round(qchisq(0.99, df),2),
                   '0.995' = round(qchisq(0.995, df),2))
chisq_table

Poisson vs geometric

p <- 0.7
l <- 0.5 #generally steeper than geometric, gets a bump as approaches l = 1
df <- tibble(x = 0:9, Geometric = round(dgeom(x, p), 4), Poisson = round(dpois(x, l), 4)) %>% gather(key, value, -x)
ggplot(df) + geom_point(aes(x = x, y = value, col =  key))

Binomial alternative MLE?

# MLE multiple observations
# x <- rbinom(10, n, p)
# x
# theta <- seq(0,1,0.001)
# m <- NULL
# for(i in 1:length(theta)){
#         m[i] <-  prod(d(x, n, theta[i]))
# }
# binom_mle2 <- tibble(theta = theta, m = m)
# MLE2 <- filter(binom_mle2, m == max(m))$theta
# print(str_c("MLE2 = ", MLE2))
# mean(rand)/n
# ggplot(binom_mle2) + geom_line(aes(x = theta, y = m))
LS0tCnRpdGxlOiAiRGlzdHJpYnV0aW9ucyIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBwYWdlZC5wcmludD1GQUxTRX0KbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkoUmxhYikKbGlicmFyeShCU0RBKQpgYGAKCiNEaXNjcmV0ZQojI1VOSUZPUk0KIyMjUG9wdWxhdGlvbiAKIyMjIzEuIE1vZGVsCmBgYHtyfQptXyA8LSAxCm4gPC0gNwpyYW5nZSA8LSBtXzpuCm1lYW4gPC0gKG4rbV8pLzIKdmFyaWFuY2UgPC0gKChuLW1fKSoobi1tXysyKSkvMTIKcHJpbnQoc3RyX2MoIm0gPSAiLCBtXywgIiwgbiA9ICIsIG4sICIsIG1lYW4gPSAiLCBtZWFuLCAiLCB2YXJpYW5jZSA9ICIsIHZhcmlhbmNlKSkKcmR1bmlmKDEwLCBuLCBtXykKZHVuaWYgPC0gdGliYmxlKHggPSByYW5nZSwgZCA9IDEvKG4tbV8rMSksIHAgPSAoeC1tXysxKS8obi1tXysxKSwKICAgICAgICAgICAgICAgIHhkID0geCpkKQpkdW5pZgpnZ3Bsb3QoZHVuaWYpICsgZ2VvbV9wb2ludChhZXMoeCA9IHgsIHkgPSBwKSkKZ2dwbG90KGR1bmlmKSArIGdlb21fcG9pbnQoYWVzKHggPSB4LCB5ID0gZCkpCmBgYAojI0JFUk5PVUxMSQojIyNQb3B1bGF0aW9uIAojIyMjMS4gTW9kZWwKYGBge3J9CiNQYXJhbWV0ZXJzCnAgPC0gMC4wMDEgI3JpZ2h0LXNrZXcgZm9yIHAgPDAuNSwgc3ltbWV0cmljIGZvciBwID0gMC41LCBsZWZ0LXNrZXcgZm9yIHAgPjAuNQpzdHJfYygicCA9ICIsIHApCgpwXzIgPC0gMC44CgojUmFuZ2UKcmFuZ2UgPC0gMDoxCiNwLm0uZi4KZGJlciA8LSBmdW5jdGlvbih4LCBwKXsKICAgICAgICBwXngqKDEtcCleKDEteCkgICNzcGVjaWFsIGNhc2Ugb2YgYmlub21pYWwsIHdoZXJlIG5fID0gMQp9CmJlcm5vdWxsaSA8LSB0aWJibGUoeCA9IHJhbmdlLAogICAgICAgICAgICAgICAgZCA9IGRiZXIoeCwgcCksCiAgICAgICAgICAgICAgICBwID0gcGJlcm4oeCwgcCkpCmJlcm5vdWxsaQpnZ3Bsb3QoYmVybm91bGxpKSArIGdlb21fcG9pbnQoYWVzKHggPSB4LCB5ID0gcCkpCmdncGxvdChiZXJub3VsbGkpICsgZ2VvbV9wb2ludChhZXMoeCA9IHgsIHkgPSBkKSkKYGBgCiMjIyMyLiBFeHBlY3RlZCB2YWx1ZXMKYGBge3J9Cm11IDwtIHAKc2lnbWFfc3F1YXJlZCA8LSBwKigxLXApCnNpZ21hIDwtIHNxcnQoc2lnbWFfc3F1YXJlZCkKCiMgeCA8LSBiZXJub3VsbGkkeAojIG0gPC0gYmVybm91bGxpJG0KI211IDwtIHN1bSh4Km0pCiNzaWdtYV9zcXVhcmVkIDwtIHN1bSgoeC1tdSleMiptKQojc2lnbWFfc3F1YXJlZCA8LSBzdW0oeF4yKm0pLW11XjIgCgpzdHJfYygibXUgPSAiLCBtdSwgIiwgc2lnbWFfc3F1YXJlZCA9ICIsIHNpZ21hX3NxdWFyZWQsICIsIHNpZ21hID0gIiwgcm91bmQoc2lnbWEsMikpCmBgYAojIyMjMy4gU2FtcGxpbmcgZGlzdHJpYnV0aW9uIG9mIHRoZSBzYW1wbGUgbWVhbiwgZXhwZWN0ZWQgdmFsdWVzCmBgYHtyfQojcmFuZ2U6IDAtMQpuIDwtIDUwMDAKZXhwX1hfYmFyIDwtIG11ICNwCnZhcl9YX2JhciA8LSBzaWdtYV9zcXVhcmVkL24gI3AoMS1wKS9uCnNkX1hfYmFyIDwtIHNxcnQodmFyX1hfYmFyKSAjc3FydChwKDEtcCkvbikKICAgICAgICAKI2lmIFggfiBiaW5vbShuLHApLCBFKFgpID0gbnAsIFYoWCkgPSBucCgxLXApCiMgRShYL24pID0gRShYKS9uID0gcAojIFYoWC9uKSA9IFYoWCkvbl4yID0gbnAoMS1wKS9uXjIgPSBwKDEtcCkvbgojIFMoWC9uKSA9IHNxcnQocCgxLXApL24pCiMgWC9uIOKJiCBOKHAsIHAoMS1wKS9uKSwgd2hlbiBib3RoIG5wIGFuZCBuKDEtcCkg4omlIDUKCnN0cl9jKCJuID0gIiwgbiwgIiwgZXhwX1hfYmFyID0gIiwgZXhwX1hfYmFyLCAiLCB2YXJfWF9iYXIgPSAiLCByb3VuZCh2YXJfWF9iYXIsMyksICIsIHNkX1hfYmFyID0gIiwgcm91bmQoc2RfWF9iYXIsMyksICIsIG4qcCA9ICIsIG4qcCwgICIsIG4qKDEtcCkgPSAiLCBuKigxLXApKQpgYGAKIyMjU2FtcGxlCmBgYHtyfQp4IDwtIHJiZXJuKG4sIHApICNhIHNpbmdsZSBvYnNlcnZhdGlvbiBvZiBiaW5vbWlhbCByYW5kb20gdmFyaWFibGUgaXMgbiBvYnNlcnZhdGlvbnMgb2YgYSBCZXJub3VsbGkgcmFuZG9tIHZhcmlhYmxlCm5fMiA8LSA2MAp4XzIgPC0gcmJlcm4obl8yLCBwXzIpCmBgYAojIyMjYS4gRXN0aW1hdGVzCmBgYHtyfQpzYW1wbGVfbWVhbiA8LSBtZWFuKHgpICNwX2hhdCwgc2FtcGxlX3RvdGFsL24sIChiaW5vbWlhbCB4L24pCnNhbXBsZV90b3RhbCA8LSBzdW0oeCkgIyh4IGJpbm9taWFsKQplc3RfdmFyX1hfYmFyIDwtIChzYW1wbGVfbWVhbiooMS1zYW1wbGVfbWVhbikpL24gI2VzdGltYXRlIHNpZ21hIHNxdWFyZWQgd2l0aCBzYW1wbGVfbWVhbgplc3Rfc2RfWF9iYXIgPC0gc3FydCgoc2FtcGxlX21lYW4qKDEtc2FtcGxlX21lYW4pKS9uKQoKc2FtcGxlX21lYW5fMiA8LSBtZWFuKHhfMikKZXN0X3Zhcl9YX2Jhcl8yIDwtIChzYW1wbGVfbWVhbl8yKigxLXNhbXBsZV9tZWFuXzIpKS9uXzIgI2VzdGltYXRlIHNpZ21hIHNxdWFyZWQgd2l0aCBzYW1wbGVfbWVhbgpleHRfdmFyX1hfYmFyX2RpZmYgPC0gZXN0X3Zhcl9YX2JhciArIGVzdF92YXJfWF9iYXJfMgplc3Rfc2RfWF9iYXJfZGlmZiA8LSBzcXJ0KGV4dF92YXJfWF9iYXJfZGlmZikKc2FtcGxlX21lYW5fZGlmZiA8LSBzYW1wbGVfbWVhbi1zYW1wbGVfbWVhbl8yCgojU2FtcGxlIHZhcmlhbmNlIG5vdGVzCiMgc2FtcGxlX3ZhciA8LSBzYW1wbGVfbWVhbiooMS1zYW1wbGVfbWVhbikgI3BfaGF0KDEtcF9oYXQpLCBiaWFzZWQgZXN0aW1hdG9yIG9mIFNfc3F1YXJlZD8KIyBzYW1wbGVfc2QgPC0gc3FydChzYW1wbGVfdmFyKQojIHNhbXBsZV92YXIyIDwtIHZhcih4KSAjc2FtcGxlIHZhcmlhbmNlCiMgc2FtcGxlX3NkMiA8LSBzcXJ0KHNhbXBsZV92YXIpCiMgc2FtcGxlX3ZhcjMgPC0gc3VtKCh4LW1lYW4oeCkpXjIpL2xlbmd0aCh4KSAjc2FtZSBhcyAxLCBiaWFzZWQ/CiMgc2FtcGxlX3NkMyA8LSBzcXJ0KHNhbXBsZV92YXIzKQoKc3RyX2MoInNhbXBsZV90b3RhbCA9ICIsIHNhbXBsZV90b3RhbCwgIiwgc2FtcGxlX21lYW4gPSAiLCBzYW1wbGVfbWVhbiwgIiwgZXN0X3Zhcl9YX2JhciA9ICIsIHJvdW5kKGVzdF92YXJfWF9iYXIsIDMpLCAiLCBlc3Rfc2RfWF9iYXIgPSAiLCByb3VuZChlc3Rfc2RfWF9iYXIsIDMpKQpgYGAKIyMjI2IuIExpa2VsaG9vZApgYGB7cn0KI01MRTogCmJlcm5vdWxsaW5fbWxlIDwtIHRpYmJsZSh0aGV0YSA9IHNlcSgwLDEsMC4wMDEpLAogICAgICAgICAgICAgICAgICAgIG0gPSBkYmlub20oc3VtKHgpLCBuLCBwID0gdGhldGEpKSAjc2luZ2xlIG9ic2VydmF0aW9uIG9mIGJpbm9taWFsCmdncGxvdChiZXJub3VsbGluX21sZSkgKyBnZW9tX2xpbmUoYWVzKHggPSB0aGV0YSwgeSA9IG0pKQpgYGAKIyMjI2MuaS4gQ29uZmlkZW5jZSBpbnRlcnZhbApgYGB7cn0KYWxwaGEgPC0gMC4wNQoKI0NvbmZpZGVuY2UgaW50ZXJ2YWwKQ0kgPC0gYyhzYW1wbGVfbWVhbiAtIHFub3JtKDEtYWxwaGEvMikqZXN0X3NkX1hfYmFyLCAKICAgICAgICBzYW1wbGVfbWVhbiArIHFub3JtKDEtYWxwaGEvMikqZXN0X3NkX1hfYmFyKQpzdHJfYygic2FtcGxlX21lYW4gPSAiLCBzYW1wbGVfbWVhbiwgIiwgQ0kgPSAiLCBwYXN0ZShyb3VuZChDSSwzKSwgY29sbGFwc2UgPSAiLCAiKSkKYGBgCiMjIyNjLmlpLiBDb25maWRlbmNlIGludGVydmFsIGRpZmZlcmVuY2Ugb2YgcHJvcG9ydGlvbnMKYGBge3J9CkNJIDwtIGMoc2FtcGxlX21lYW5fZGlmZiAtIHFub3JtKDEtYWxwaGEvMikqZXN0X3NkX1hfYmFyX2RpZmYsIAogICAgICAgIHNhbXBsZV9tZWFuX2RpZmYgKyBxbm9ybSgxLWFscGhhLzIpKmVzdF9zZF9YX2Jhcl9kaWZmKQpzdHJfYygic2FtcGxlX21lYW5fZGlmZiA9ICIsIHJvdW5kKHNhbXBsZV9tZWFuX2RpZmYsMyksICIsIENJID0gIiwgcGFzdGUocm91bmQoQ0ksMyksIGNvbGxhcHNlID0gIiwgIikpCmBgYAoKIyMjI2QuIEh5cG90aGVzaXMgdGVzdApgYGB7cn0KYWxwaGEgPC0gMC4wNQpwXzAgPSAwLjMKY3JpdGljYWxfdmFsdWVzIDwtIGMocF8wIC0gcW5vcm0oMS1hbHBoYS8yKSooc3FydChwXzAqKDEtcF8wKS9uKSksCiAgICAgICAgICAgICAgICAgICAgIHBfMCArIHFub3JtKDEtYWxwaGEvMikqKHNxcnQocF8wKigxLXBfMCkvbikpKSAjbm90IHBfaGF0Pwp6IDwtICgoc2FtcGxlX21lYW4tcF8wKSkvKHNxcnQocF8wKigxLXBfMCkvbikpCnN0YW5kYXJkX2NyaXRpY2FsX3ZhbHVlcyA8LSBjKHFub3JtKGFscGhhLzIpLCBxbm9ybSgxLWFscGhhLzIpKQoKcF92YWx1ZSA8LSAyKigxLXBub3JtKGFicyh6KSkpCnN0cl9jKCJIMDogcF8wID0gIiwgcF8wKQpzdHJfYygiY3JpdGljYWwgdmFsdWVzID0gIiwgcGFzdGUocm91bmQoY3JpdGljYWxfdmFsdWVzLDMpLGNvbGxhcHNlID0gIiwgIikpCnN0cl9jKCJzYW1wbGVfbWVhbiA9ICIsIHJvdW5kKHNhbXBsZV9tZWFuLDMpKQpzdHJfYygic3RhbmRhcmQgY3JpdGljYWwgdmFsdWVzID0gIiwgcGFzdGUocm91bmQoc3RhbmRhcmRfY3JpdGljYWxfdmFsdWVzLDMpLGNvbGxhcHNlID0gIiwgIikpCnN0cl9jKCJ6ID0gIiwgcm91bmQoeiwgMykpCnN0cl9jKCJwX3ZhbHVlID0gIiwgcm91bmQocF92YWx1ZSwgNSkpCgpwcm9wLnRlc3Qoc2FtcGxlX3RvdGFsLCBuLCBwXzAsIGNvcnJlY3QgPSBGQUxTRSkgI0NJIHNsaWdodGx5IGRpZmZlcmVudD8/CmBgYAojI0JJTk9NSUFMCiMjI1BvcHVsYXRpb24gCiMjIyMxLiBNb2RlbApgYGB7cn0KI251bWJlciBvZiBzdWNjZXNzZXMgaW4gYSBzZXF1ZW5jZSBvZiBuIGluZGVwZW5kZW50IEJlcm5vdWxsaSB0cmlhbHMgd2l0aCBwcm9iYWJpbGl0eSBwCm5fIDwtIDMwMDAgI2Zpbml0ZSByYW5nZSwgQmVybm91bGxpIGlmIG4gPSAxCnAgPC0gMTIvMzAwMAojIHAgPC0gbC9uXyAKI3JpZ2h0LXNrZXcgZm9yIHAgPDAuNSwgc3ltbWV0cmljIGZvciBwID0gMC41LCBsZWZ0LXNrZXcgZm9yIHAgPjAuNQojVGhlIFBvaXNzb24gZGlzdHJpYnV0aW9uIGlzIHRoZSBsaW1pdGluZyBkaXN0cmlidXRpb24gb2YgWCB+IEIobiwgbC9uKQojSWYgbiBpcyBsYXJnZSBhbmQgcCBpcyBzbWFsbCAobiDiiaUgNTAgYW5kIHAg4omkIDAuMDUpIHRoZW4gdGhlIGJpbm9taWFsIHJhbmRvbSB2YXJpYWJsZSBCKG4scCkgaGFzIGFwcHJveGltYXRlbHkgdGhlIHNhbWUgZGlzdHJpYnV0aW9uIGFzIFBvaXNzb24obnApCgojIHJhbmdlIDwtIDA6bl8KcmFuZ2UgPC0gMDo1MAoKZGIgPC0gZnVuY3Rpb24oeCwgbl8sIHApewogICAgICAgIGNob29zZShuXywgeCkqcF54KigxLXApXihuXy14KQp9CmJpbm9tIDwtIHRpYmJsZSh4ID0gcmFuZ2UsCiAgICAgICAgICAgICAgICBkID0gZGIoeCwgbl8sIHApLCAjb25lIG1vZGUsIGNhbiB0YWtlIGFueSB2YWx1ZSwgZGVwZW5kcyBvbiBwCiAgICAgICAgICAgICAgICBwID0gcGJpbm9tKHgsIG5fLCBwKSkKYmlub20KZ2dwbG90KGJpbm9tKSArIGdlb21fcG9pbnQoYWVzKHggPSB4LCB5ID0gcCkpCmdncGxvdChiaW5vbSkgKyBnZW9tX3BvaW50KGFlcyh4ID0geCwgeSA9IGQpKQpgYGAKIyMjIzIuIEV4cGVjdGVkIHZhbHVlcwpgYGB7cn0KeCA8LSBiaW5vbSR4CmQgPC0gYmlub20kZAptdSA8LSBuXypwICNsaW5lYXIsIHJhbmdlcyBmcm9tIDAgPCBtZWFuIDwgbgojbXUgPC0gc3VtKHgqbSkKc2lnbWFfc3F1YXJlZCA8LSBuXypwKigxLXApICNxdWFkcmF0aWMsIG1heCAwLjI1biwgdmFyIC0+IG1lYW4gYXMgcCAtPiAwLCBtZWFuIC0gdmFyIC0+IG4gYXMgcCAtPiAxCiNzaWdtYV9zcXVhcmVkIDwtIHN1bSgoeC1tdSleMiptKQojc2lnbWFfc3F1YXJlZCA8LSBzdW0oeF4yKm0pLW11XjIgCnNpZ21hIDwtIHNxcnQoc2lnbWFfc3F1YXJlZCkKc3RyX2MoIm11IChucCkgPSAiLCBtdSwgIiwgc2lnbWFfc3F1YXJlZCAobnAoMS1wKSkgPSAiLCBzaWdtYV9zcXVhcmVkLCAiLCBzaWdtYSA9ICIsIHJvdW5kKHNpZ21hLDIpKQpgYGAKIyMjIzMuIFNhbXBsaW5nIGRpc3RyaWJ1dGlvbnMgb2YgdGhlIHNhbXBsZSBtZWFuLCBleHBlY3RlZCB2YWx1ZXMKYGBge3J9Cm4gPC0gNTAKZXhwX1hfYmFyIDwtIG11CnZhcl9YX2JhciA8LSBzaWdtYV9zcXVhcmVkL24gI3AqKDEtcCkgKHNhbWUgYXMgc2lnbWFfc3F1YXJlZCBCZXJub3VsbGkpCnNkX1hfYmFyIDwtIHNxcnQodmFyX1hfYmFyKQoKc3RyX2MoIm4gPSAiLCBuLCAiLCBleHBfWF9iYXIgPSAiLCBleHBfWF9iYXIsICIsIHZhcl9YX2JhciA9ICIsIHJvdW5kKHZhcl9YX2JhciwzKSwgIiwgc2RfWF9iYXIgPSAiLCByb3VuZChzZF9YX2JhciwzKSkKYGBgCiMjUE9JU1NPTgojIyNQb3B1bGF0aW9uIAojIyMjMS4gTW9kZWwKYGBge3J9CiNUaGUgUG9pc3NvbiBkaXN0cmlidXRpb24gaXMgdGhlIGxpbWl0aW5nIGRpc3RyaWJ1dGlvbiBvZiBYIH4gQihuLCBsL24pCiNJZiBuIGlzIGxhcmdlIGFuZCBwIGlzIHNtYWxsIChuIOKJpSA1MCBhbmQgcCDiiaQgMC4wNSkgdGhlbiB0aGUgYmlub21pYWwgcmFuZG9tIHZhcmlhYmxlIEIobixwKSBoYXMgYXBwcm94aW1hdGVseSB0aGUgc2FtZSBkaXN0cmlidXRpb24gYXMgUG9pc3NvbihucCkKI0ZvciBhIFBvaXNzb24gcHJvY2VzcyBpbiB3aGljaCBldmVudHMgb2NjdXIgYXQgcmFuZG9tIGF0IHJhdGUgbCwgdGhlIG51bWJlciBvZiBldmVudHMgdGhhdCBvY2N1ciBkdXJpbmcgYSB0aW1lIGludGVydmFsIG9mIGxlbmd0aCB0IGhhcyBhIFBvaXNzb24gZGlzdHJpYnV0aW9uIHdpdGggcGFyYW1ldGVyIGx0CmwgPC0gMC4xICNjb25zdGFudCBldmVudCByYXRlCnQgPC0gMTAwICN0aW1lIGludGVydmFsCmx0IDwtIGwqdCAjZGVjcmVhc2luZyBwLm0uZi4gd2hlbiBsdCA8IDEKc3RyX2MoInJhdGUgPSAiLCBsLCAiLCB0aW1lID0gIiwgdCwgIiwgbHQgPSAiLCBsdCkKI1JhbmdlCnJhbmdlIDwtIDA6NTAgI3VuYm91bmRlZCB0byB0aGUgcmlnaHQKI3AuZC5mCmRwIDwtIGZ1bmN0aW9uKHgsIGx0KXsKICAgICAgICAoZXhwKDEpXigtbHQpKmx0XngpL2ZhY3RvcmlhbCh4KQp9CnBvaXNzb24gPC0gdGliYmxlKHggPSByYW5nZSwKICAgICAgICAgICAgICAgIGQgPSBkcCh4LCBsdCksICNvbmUgbW9kZSwgY2FuIHRha2UgYW55IHZhbHVlCiAgICAgICAgICAgICAgICBwID0gcHBvaXMoeCwgbHQpKQpwb2lzc29uCmdncGxvdChwb2lzc29uKSArIGdlb21fcG9pbnQoYWVzKHggPSB4LCB5ID0gcCkpCmdncGxvdChwb2lzc29uKSArIGdlb21fcG9pbnQoYWVzKHggPSB4LCB5ID0gZCkpCmBgYAojIyMjMi4gRXhwZWN0ZWQgdmFsdWVzCmBgYHtyfQojTXUsIHNpZ21hCm11IDwtIGx0CnNpZ21hX3NxdWFyZWQgPC0gbHQKc2lnbWEgPC0gc3FydChzaWdtYV9zcXVhcmVkKQoKc3RyX2MoIm11ID0gIiwgbXUsICIsIHNpZ21hX3NxdWFyZWQgPSAiLCBzaWdtYV9zcXVhcmVkLCAiLCBzaWdtYSA9ICIsIHJvdW5kKHNpZ21hLDMpKQpgYGAKIyMjIzMuIFNhbXBsaW5nIGRpc3RyaWJ1dGlvbiBvZiB0aGUgc2FtcGxlIG1lYW4sIGV4cGVjdGVkIHZhbHVlcwpgYGB7cn0KbiA8LSAxMDAwCmV4cF9YX2JhciA8LSBtdQp2YXJfWF9iYXIgPC0gc2lnbWFfc3F1YXJlZC9uCnNkX1hfYmFyIDwtIHNxcnQodmFyX1hfYmFyKQpzdHJfYygibiA9ICIsIG4sICIsIGV4cF9YX2JhciA9ICIsIGV4cF9YX2JhciwgIiwgdmFyX1hfYmFyID0gIiwgcm91bmQodmFyX1hfYmFyLDMpLCAiLCBzZF9YX2JhciA9ICIsIHJvdW5kKHNkX1hfYmFyLDMpKQpgYGAKWzFdICJuID0gMTAwMCwgZXhwX1hfYmFyID0gMC4xLCB2YXJfWF9iYXIgPSAwLCBzZF9YX2JhciA9IDAuMDEiCgpbMV0gIm4gPSAxMDAsIGV4cF9YX2JhciA9IDEsIHZhcl9YX2JhciA9IDAuMDEsIHNkX1hfYmFyID0gMC4xIgoKWzFdICJuID0gMTAsIGV4cF9YX2JhciA9IDEwLCB2YXJfWF9iYXIgPSAxLCBzZF9YX2JhciA9IDEiCgoKIyMjU2FtcGxlCmBgYHtyfQp4IDwtIHJwb2lzKG4sIGx0KQoKIyBPIDwtIGMoMjEsOCw2LDEpCiMgbiA8LSBzdW0oTykKIyByYW5nZSA8LSAwOihsZW5ndGgoTyktMSkKIyB4IDwtIHJlcChyYW5nZSwgTykKCiNFLmNvbGkKI3ggPC0gYygzMjc0LDMxOTgsMzI1OCwzMjc2LDM0NTYsMzM4NCwzMjgwLDMwODEsMzA2MiwzMDIzLDMwNzMsMjc5NCwzMDY4KQpgYGAKIyMjI2EuIEVzdGltYXRlcwpgYGB7cn0Kc3RyX2MoImx0ID0gIiwgbHQpICNjYW4gdXNlIG5vcm1hbCBhcHByb3hpbWF0aW9uIHdoZW4gbHQgPj0gMzAKCnNhbXBsZV9tZWFuIDwtIG1lYW4oeCkgI2xfaGF0Cgplc3RfdmFyX1hfYmFyIDwtIHNhbXBsZV9tZWFuL24gI2VzdGltYXRlIHNpZ21hIHNxdWFyZWQgd2l0aCBzYW1wbGVfbWVhbgplc3Rfc2RfWF9iYXIgPC0gc3FydChzYW1wbGVfbWVhbi9uKQoKc3RyX2MoInNhbXBsZV9tZWFuIChsX2hhdCkgPSAiLCByb3VuZChzYW1wbGVfbWVhbiwzKSwgIiwgZXN0X3Zhcl9YX2JhciA9ICIsIHJvdW5kKGVzdF92YXJfWF9iYXIsMyksICIsIGVzdF9zZF9YX2JhciA9ICIsIHJvdW5kKGVzdF9zZF9YX2JhciwzKSkKYGBgCiMjIyNiLiBMaWtlbGhvb2QKYGBge3J9CnRoZXRhIDwtIHNlcSgwLG1heChyYW5nZSksIG1heChyYW5nZSkvMTAwMCkKbHAgPC0gZnVuY3Rpb24oeCwgdGhldGEpewogICAgICAgIG4gPC0gbGVuZ3RoKHgpCiAgICAgICAgYyA8LSAxL3Byb2QoZmFjdG9yaWFsKHgpKQogICAgICAgIHNhbXBsZV9tZWFuIDwtIG1lYW4oeCkKICAgICAgICBjKmV4cCgxKV4oLW4qdGhldGEpKnRoZXRhXihuKnNhbXBsZV9tZWFuKQp9CnBvaXNzb25fbWxlIDwtIHRpYmJsZSh0aGV0YSA9IHRoZXRhLCBtID0gbHAoeCwgdGhldGEpKQpnZ3Bsb3QocG9pc3Nvbl9tbGUpICsgZ2VvbV9saW5lKGFlcyh4ID0gdGhldGEsIHkgPSBtKSkKYGBgCiMjIyNjLiBDb25maWRlbmNlIGludGVydmFsCmBgYHtyfQphbHBoYSA8LSAwLjA1CnN0cl9jKCJhbHBoYSA9ICIsIGFscGhhKQoKI0NvbmZpZGVuY2UgaW50ZXJ2YWwKQ0kgPC0gYyhzYW1wbGVfbWVhbiAtIHFub3JtKDEtYWxwaGEvMikqZXN0X3NkX1hfYmFyLCAKICAgICAgICBzYW1wbGVfbWVhbiArIHFub3JtKDEtYWxwaGEvMikqZXN0X3NkX1hfYmFyKQpzdHJfYygiQ0kgPSAiLCBwYXN0ZShyb3VuZChDSSwzKSwgY29sbGFwc2UgPSAiLCAiKSkKYGBgCiJDSSA9IDAuMDU5LCAwLjA5MyIKQ0kqMTAwID0gNS45IDkuMwoKIkNJID0gMC43MzIsIDEuMTA4IgpDSSoxMCA9IDcuMzIgMTEuMDgKCiJDSSA9IDYuNjkzLCAxMC4zMDciCgoKIyNHRU9NRVRSSUMKIyMjUG9wdWxhdGlvbiAKIyMjIzEuIE1vZGVsCmBgYHtyfQpwIDwtIDAuOApzdHJfYygicCA9ICIsIHApCnJhbmdlIDwtIDE6MTAgIzEsMiwzLC4uLiwgdW5ib3VuZGVkIHRvIHRoZSByaWdodAojcC5tLmYuCmRnIDwtIGZ1bmN0aW9uKHgsIHApewogICAgICAgICgoMS1wKV4oeC0xKSkqcAp9CiNjLmQuZi4KcGcgPC0gZnVuY3Rpb24oeCwgcCl7CiAgICAgICAgMS0oMS1wKV54Cn0KZ2VvbSA8LSB0aWJibGUoeCA9IHJhbmdlLCAKICAgICAgICAgICAgICAgIGQgPSBkZyh4LCBwKSwgI2RlY3JlYXNpbmcgcC5tLmYuLCBtb2RlIGFsd2F5cyBhdCAxIAogICAgICAgICAgICAgICAgcCA9IHBnKHgsIHApKQpnZW9tCmdncGxvdChnZW9tKSArIGdlb21fcG9pbnQoYWVzKHggPSB4LCB5ID0gcCkpCmdncGxvdChnZW9tKSArIGdlb21fcG9pbnQoYWVzKHggPSB4LCB5ID0gZCkpCmBgYAojIyMjMi4gRXhwZWN0ZWQgdmFsdWVzCmBgYHtyfQojTXUsIHNpZ21hCm11IDwtIDEvcCAjbWVhbiA8IHZhcmlhbmNlIGZvciBwIDwgMC41LCBtZWFuID4gdmFyaWFuY2UgZm9yIHAgPiAwLjUKc2lnbWFfc3F1YXJlZCA8LSAoMS1wKS9wXjIKc2lnbWEgPC0gc3FydChzaWdtYV9zcXVhcmVkKQpzdHJfYygibXUgPSAiLCBtdSwgIiwgc2lnbWFfc3F1YXJlZCA9ICIsIHNpZ21hX3NxdWFyZWQsICIsIHNpZ21hID0gIiwgc2lnbWEpCmBgYAojIyNTYW1wbGUKYGBge3J9CnggPC0gcmdlb20oMTAwLCBwKSArIDEgI3NoaWZ0ZWQgZ2VvbWV0cmljIGRpc3RyaWJ1dGlvbgpgYGAKIyMjI2EuIEVzdGltYXRlcwpgYGB7cn0Kc2FtcGxlX21lYW4gPC0gbWVhbih4KQpwX2hhdCA8LSAxL3NhbXBsZV9tZWFuICNiaWFzZWQKCnN0cl9jKCdzYW1wbGVfbWVhbiA9ICcsIHJvdW5kKHNhbXBsZV9tZWFuLDIpLCAiLCBwX2hhdCA9ICIsIHJvdW5kKHBfaGF0LDIpKQpgYGAKIyMjI2IuIExpa2VsaG9vZApgYGB7cn0KdGhldGEgPC0gc2VxKDAsMSwwLjAwMSkKbGcgPC0gZnVuY3Rpb24oeCwgdGhldGEpewogICAgICAgIG4gPC0gbGVuZ3RoKHgpCiAgICAgICAgKDEtdGhldGEpXihzdW0oeCktbikqdGhldGFebgp9Cmdlb21fbWxlIDwtIHRpYmJsZSh0aGV0YSA9IHRoZXRhLCBtID0gbGcoeCwgdGhldGEpKQpnZ3Bsb3QoZ2VvbV9tbGUpICsgZ2VvbV9saW5lKGFlcyh4ID0gdGhldGEsIHkgPSBtKSkKYGBgCiMjTkVHQVRJVkUgQklOT01JQUwKIyMjUG9wdWxhdGlvbiAKIyMjIzEuIE1vZGVsCmBgYHtyfQpyIDwtIDUKcCA8LSAwLjUKc3RyX2MoInAgPSAiLCBwLCAiLCByID0gIiwgcikKcmFuZ2UgPC0gMDo1MCAjMSwyLDMsLi4uLCB1bmJvdW5kZWQgdG8gdGhlIHJpZ2h0CiNwLm0uZi4KI2MuZC5mLgoKbmIgPC0gdGliYmxlKHggPSByYW5nZSwgCiAgICAgICAgICAgICAgICBkID0gZG5iaW5vbSh4LCByLCBwKSwgCiAgICAgICAgICAgICAgICBwID0gcG5iaW5vbSh4LCByLCBwKSkKbmIKZ2dwbG90KG5iKSArIGdlb21fcG9pbnQoYWVzKHggPSB4LCB5ID0gcCkpCmdncGxvdChuYikgKyBnZW9tX3BvaW50KGFlcyh4ID0geCwgeSA9IGQpKQpgYGAKCiNDb250aW51b3VzCiMjVU5JRk9STQojIyNQb3B1bGF0aW9uIAojIyMjMS4gTW9kZWwKYGBge3J9CmEgPC0gMQpiIDwtIDUKbWVhbiA8LSAoYStiKS8yCnZhcmlhbmNlIDwtIChiLWEpXjIvMTIKcmFuZ2UgPC0gYyhhLGIpCnByaW50KHN0cl9jKCJhID0gIiwgYSwgIiwgYiA9ICIsIGIsICIsIG1lYW4gPSAiLCBtZWFuLCAiLCB2YXJpYW5jZSA9ICIsIHZhcmlhbmNlKSkKCnVuaWYgPC0gdGliYmxlKHggPSByYW5nZSwgZCA9IDEvKGItYSksIHAgPSAoeC1hKS8oYi1hKSkKdW5pZgpnZ3Bsb3QodW5pZikgKyBnZW9tX2xpbmUoYWVzKHggPSB4LCB5ID0gcCkpCmdncGxvdCh1bmlmKSArIGdlb21fbGluZShhZXMoeCA9IHgsIHkgPSBkKSkKYGBgCiMjI1NhbXBsZQpgYGB7cn0KeCA8LSBydW5pZigxMCwgYSwgYikKYGBgCiMjRVhQT05FTlRJQUwKIyMjUG9wdWxhdGlvbiAKIyMjIzEuIE1vZGVsCmBgYHtyfQojRm9yIGEgUG9pc3NvbiBwcm9jZXNzIHdpbiB3aGljaCBldmVudHMgb2NjdXIgYXQgcmFuZG9tIGF0IHJhdGUgbCwgdGhlIHdhaXRpbmcgdGltZSBiZXR3ZWVuIHN1Y2Nlc3NpdmUgZXZlbnRzIGhhcyBhbiBleHBvbmVudGlhbCBkaXN0cmlidXRpb24gd2l0aCBwYXJhbWV0ZXIgbAojUGFyYW1ldGVycwpsIDwtIDEvMjYgI3JhdGUKcmFuZ2UgPC0gc2VxKDAuMDAwMSwgMTAwLCAxMDAvMTAwMCkgIyBYID4gMCwgdW5ib3VuZGVkIHRvIHRoZSByaWdodApzdHJfYygibGFtYmRhID0gIiwgbCkKCiNwLmQuZi4KZGUgPC0gZnVuY3Rpb24oeCwgbCl7CiAgICAgIGwqZXhwKDEpXigtbCp4KSAjZGVjcmVhc2luZyBwLmQuZi4gIAp9CgojYy5kLmYuCnBlIDwtIGZ1bmN0aW9uKHgsIGwpewogICAgICAgIHAgPSAxLWV4cCgxKV4oLWwqeCkKfQoKZXhwb25lbnRpYWwgPC0gdGliYmxlKHggPSByYW5nZSwgCiAgICAgICAgICAgICAgICBkID0gZGUoeCwgbCksCiAgICAgICAgICAgICAgICBwID0gcGUoeCwgbCkpCmV4cG9uZW50aWFsCmdncGxvdChleHBvbmVudGlhbCkgKyBnZW9tX2xpbmUoYWVzKHggPSB4LCB5ID0gcCkpCmdncGxvdChleHBvbmVudGlhbCkgKyBnZW9tX2xpbmUoYWVzKHggPSB4LCB5ID0gZCkpCmBgYAojIyMjMi4gRXhwZWN0ZWQgdmFsdWVzCmBgYHtyfQojTXUsIHNpZ21hCm11IDwtIDEvbApzaWdtYV9zcXVhcmVkIDwtIDEvbF4yCnNpZ21hIDwtIHNxcnQoc2lnbWFfc3F1YXJlZCkgI211ID0gc2lnbWEKCnN0cl9jKCJtdSA9ICIsIG11LCAiLCBzaWdtYV9zcXVhcmVkID0gIiwgc2lnbWFfc3F1YXJlZCwgIiwgc2lnbWEgPSAiLCBzaWdtYSkKYGBgCgojIyNTYW1wbGUKYGBge3J9CnggPC0gcmV4cCgxMCwgbCkKYGBgCiMjIyNhLiBFc3RpbWF0ZXMKYGBge3J9CnNhbXBsZV9tZWFuIDwtIG1lYW4oeCkKbF9oYXQgPSAxL3NhbXBsZV9tZWFuICNiaWFzZWQKYGBgCiMjIyNiLiBMaWtlbGhvb2QKYGBge3J9CnRoZXRhIDwtIHNlcSgwLDMqbCwgMypsLzEwMDApCgpzdHJfYygnc2FtcGxlX21lYW4gPSAnLCByb3VuZChzYW1wbGVfbWVhbiwyKSwgIiwgbF9oYXQgPSAiLCByb3VuZChsX2hhdCwyKSkKCmxlIDwtIGZ1bmN0aW9uKHgsIHRoZXRhKXsKICAgICAgICBuIDwtIGxlbmd0aCh4KQogICAgICAgIHNhbXBsZV9tZWFuIDwtIG1lYW4oeCkKICAgICAgICAodGhldGFebikqZXhwKDEpXigtdGhldGEqbipzYW1wbGVfbWVhbikKfQpleHBvbmVudGlhbF9tbGUgPC0gdGliYmxlKHRoZXRhID0gdGhldGEsIG0gPSBsZSh4LCB0aGV0YSkpCmdncGxvdChleHBvbmVudGlhbF9tbGUpICsgZ2VvbV9saW5lKGFlcyh4ID0gdGhldGEsIHkgPSBtKSkKYGBgCiMjTk9STUFMCiMjI1BvcHVsYXRpb24gCiMjIyMxLiBNb2RlbApgYGB7cn0KI1BhcmFtZXRlcnMKbXUgPC0gNwpzaWdtYV9zcXVhcmVkIDwtIDEwMApzaWdtYSA8LSBzcXJ0KHNpZ21hX3NxdWFyZWQpCnN0cl9jKCJtdSA9ICIsIG11LCAiLCBzaWdtYV9zcXVhcmVkID0gIiwgc2lnbWFfc3F1YXJlZCwgIiwgc2lnbWEgPSAiLCBzaWdtYSkKCm11XzIgPC0gOQoKI1JhbmdlCnJhbmdlIDwtIHNlcShtdS00KnNpZ21hLCBtdSs0KnNpZ21hLCBzaWdtYS8xMikgI3VuYm91bmRlZCAKCiNwLmQuZi4KZG4gPC0gZnVuY3Rpb24oeCwgbXUsIHNpZ21hKXsKICAgICAgICAoMS8oc2lnbWEqc3FydCgyKnBpKSkpKmV4cCgtMC41KigoeC1tdSkvc2lnbWEpXjIpCn0Kbm9ybWFsIDwtIHRpYmJsZSh4ID0gcmFuZ2UsCiAgICAgICAgICAgICAgICAgZCA9IGRuKHgsIG11LCBzaWdtYSksICNzeW1tZXRyaWMgYWJvdXQgbWVhbgogICAgICAgICAgICAgICAgIHAgPSBwbm9ybSh4LCBtdSwgc2lnbWEpKQpub3JtYWwKZ2dwbG90KG5vcm1hbCkgKyBnZW9tX2xpbmUoYWVzKHggPSB4LCB5ID0gcCkpCmdncGxvdChub3JtYWwpICsgZ2VvbV9saW5lKGFlcyh4ID0geCwgeSA9IGQpKQpgYGAKIyMjIzIuIEV4cGVjdGVkIHZhbHVlcwpgYGB7cn0Kc3RyX2MoIm11ID0gIiwgbXUsICIsIHNpZ21hX3NxdWFyZWQgPSAiLCBzaWdtYV9zcXVhcmVkLCAiLCBzaWdtYSA9ICIsIHJvdW5kKHNpZ21hLDMpKQpgYGAKIyMjIzMuIFNhbXBsaW5nIGRpc3RyaWJ1dGlvbnMgb2YgdGhlIHNhbXBsZSBtZWFuLCBleHBlY3RlZCB2YWx1ZXMKYGBge3J9Cm4gPC0gMjAKCmV4cF9YX2JhciA8LSBtdQp2YXJfWF9iYXIgPC0gc2lnbWFfc3F1YXJlZC9uCnNkX1hfYmFyIDwtIHNpZ21hL3NxcnQobikKc3RyX2MoIm4gPSAiLCBuLCAiLCBleHBfWF9iYXIgPSAiLCByb3VuZChleHBfWF9iYXIsMyksICIsIHZhcl9YX2JhciA9ICIsIHJvdW5kKHZhcl9YX2JhciwzKSwgIiwgc2RfWF9iYXIgPSAiLCByb3VuZChzZF9YX2JhciwzKSkKYGBgCiMjIyM0LiBTYW1wbGluZyBkaXN0cmlidXRpb24gb2YgdGhlIHNhbXBsZSB2YXJpYW5jZSwgZXhwZWN0ZWQgdmFsdWVzCmBgYHtyfQpleHBfU19zcXVhcmVkIDwtIHNpZ21hX3NxdWFyZWQKZXhwX1MgPC0gc2lnbWEKc3RyX2MoImV4cF9TX3NxdWFyZWQgPSAiLCByb3VuZChleHBfU19zcXVhcmVkLDMpLCAiLCBleHBfUyA9ICIsIHJvdW5kKGV4cF9TLDMpKQpgYGAKCiMjI1NhbXBsZQpgYGB7cn0KeCA8LSBybm9ybShuLCBtdSwgc2lnbWEpCgpuXzIgPC0gMzAKeF8yIDwtIHJub3JtKG4sIG11XzIsIHNpZ21hKQojIHggPC0gYygtNiwxLDIsNCwyNCwyNywzMykKIyBuIDwtIGxlbmd0aCh4KQpgYGAKIyMjI2EuIEVzdGltYXRlcwpgYGB7cn0Kc2FtcGxlX21lYW4gPC0gbWVhbih4KSAjbXVfaGF0CgpzYW1wbGVfdmFyIDwtIHZhcih4KSAjc19zcXVhcmVkCnNhbXBsZV9zZCA8LSBzcXJ0KHNhbXBsZV92YXIpICNzCgpzYW1wbGVfbWVhbl8yIDwtIG1lYW4oeF8yKQpzYW1wbGVfdmFyXzIgPC0gdmFyKHhfMikKc2FtcGxlX3Zhcl9wb29sZWQgPC0gKChuLTEpKnNhbXBsZV92YXIrKG5fMi0xKSpzYW1wbGVfdmFyXzIpLyhuK25fMi0yKQpzYW1wbGVfc2RfcG9vbGVkIDwtIHNxcnQoc2FtcGxlX3Zhcl9wb29sZWQpCnNhbXBsZV9tZWFuX2RpZmYgPC0gc2FtcGxlX21lYW4tc2FtcGxlX21lYW5fMgoKIyBzaWdtYV9zcXVhcmVkX2hhdCA8LSBzdW0oKHgtbWVhbih4KSleMikvbGVuZ3RoKHgpICNiaWFzZWQKIyBzaWdtYV9oYXQgPC0gc3FydChzdW0oKHgtbWVhbih4KSleMikvbGVuZ3RoKHgpKSAjYmlhc2VkCgplc3RfdmFyX1hfYmFyIDwtIHNhbXBsZV92YXIvbiAjZXN0aW1hdGUgc2lnbWFfc3F1YXJlZCB3aXRoIHNhbXBsZV92YXIKZXN0X3NkX1hfYmFyIDwtIHNhbXBsZV9zZC9zcXJ0KG4pICNlc3RpbWF0ZSBzaWdtYSB3aXRoIHNhbXBsZV9zZAoKc3RyX2MoInNhbXBsZV9tZWFuID0gIiwgcm91bmQoc2FtcGxlX21lYW4sMyksICIsIHNhbXBsZV92YXIgPSAiLCByb3VuZChzYW1wbGVfdmFyLDMpLCAiLCBzYW1wbGVfc2QgPSAiLCByb3VuZChzYW1wbGVfc2QsMyksICIsIGVzdF92YXJfWF9iYXIgPSAiLCByb3VuZChlc3RfdmFyX1hfYmFyLDMpLCAiLCBlc3Rfc2RfWF9iYXIgPSAiLCByb3VuZChlc3Rfc2RfWF9iYXIsMykpCmBgYAojIyMjYy4gQ29uZmlkZW5jZSBpbnRlcnZhbApgYGB7cn0KYWxwaGEgPC0gMC4wNQpzdHJfYygiYWxwaGEgPSAiLCBhbHBoYSkKCiNDb25maWRlbmNlIGludGVydmFsCkNJIDwtIGMoc2FtcGxlX21lYW4gLSBxbm9ybSgxLWFscGhhLzIpKmVzdF9zZF9YX2JhciwgCiAgICAgICAgc2FtcGxlX21lYW4gKyBxbm9ybSgxLWFscGhhLzIpKmVzdF9zZF9YX2JhcikKc3RyX2MoIkNJID0gIiwgcGFzdGUocm91bmQoQ0ksMyksIGNvbGxhcHNlID0gIiwgIikpCmBgYAojIyMjZC4gSHlwb3RoZXNpcyB0ZXN0CmBgYHtyfQptdV8wID0gNwpjcml0aWNhbF92YWx1ZXMgPC0gYyhtdV8wIC0gcW5vcm0oMS1hbHBoYS8yKSplc3Rfc2RfWF9iYXIsCiAgICAgICAgICAgICAgICAgICAgIG11XzAgKyBxbm9ybSgxLWFscGhhLzIpKmVzdF9zZF9YX2JhcikKeiA8LSAoc2FtcGxlX21lYW4tbXVfMCkvZXN0X3NkX1hfYmFyICN3aGVuIEhfMCBpcyB0cnVlLCBaIH4gTigwLDEpCnN0YW5kYXJkX2NyaXRpY2FsX3ZhbHVlcyA8LSBjKHFub3JtKGFscGhhLzIpLCBxbm9ybSgxLWFscGhhLzIpKQpwX3ZhbHVlIDwtIDIqKDEtcG5vcm0oYWJzKHopKSkKCnN0cl9jKCJIMDogbXVfMCA9ICIsIG11XzApCnN0cl9jKCJjcml0aWNhbCB2YWx1ZXMgPSAiLCBwYXN0ZShyb3VuZChjcml0aWNhbF92YWx1ZXMsMyksY29sbGFwc2UgPSAiLCAiKSkKc3RyX2MoInNhbXBsZV9tZWFuID0gIiwgcm91bmQoc2FtcGxlX21lYW4sMykpCnN0cl9jKCJzdGFuZGFyZCBjcml0aWNhbCB2YWx1ZXMgPSAiLCBwYXN0ZShyb3VuZChzdGFuZGFyZF9jcml0aWNhbF92YWx1ZXMsMyksY29sbGFwc2UgPSAiLCAiKSkKc3RyX2MoInogPSAiLCByb3VuZCh6LCAzKSkKc3RyX2MoInBfdmFsdWUgPSAiLCByb3VuZChwX3ZhbHVlLCA1KSkKCnoudGVzdCh4LCBtdSA9IG11XzAsIHNpZ21hLnggPSBzYW1wbGVfc2QpCmBgYAojIyMjZS4gUG93ZXIgYW5kIHNhbXBsZSBzaXplCmBgYHtyfQojV2hlbiBIXzEgaXMgdHJ1ZSwgbXUgPSBtdV8wICsgZCwgWiAtIGQvc2RfWF9iYXIgfiBOKDAsMSkKZCA8LSAgMgpzaWdtYSA8LSA1Cm4gPC0gMzAKc2RfWF9iYXIgPC0gc2lnbWEvc3FydChuKQphbHBoYSA8LSAwLjA1CmRfeiA8LSBkL3NkX1hfYmFyCnBvd2VyIDwtIDEgLSBwbm9ybShxbm9ybSgxLWFscGhhLzIpIC0gZF96KQpzdHJfYygiZCA9ICIsIGQsICIsIGRfeiA9ICIsIHJvdW5kKGRfeiwzKSwgICIsIHBvd2VyID0gIiwgcm91bmQocG93ZXIsNCkpCmBgYAojIyMjZi4gU2FtcGxlIHNpemUKYGBge3J9CmdhbW1hIDwtIDAuOQpzYW1wbGVfc2l6ZSA8LSAoc2lnbWFfc3F1YXJlZC9kXjIpKihxbm9ybSgxLWFscGhhLzIpIC0gcW5vcm0oMS1nYW1tYSkpXjIKCnN0cl9jKCJkID0gIiwgZCwgICIsIGdhbW1hID0gIiwgZ2FtbWEsICIsIHNhbXBsZSBzaXplID0gIiwgY2VpbGluZyhzYW1wbGVfc2l6ZSkpCmBgYAoKIyNTVFVERU5UJ1MgVAojIyNQb3B1bGF0aW9uIAojIyMjMS4gTW9kZWwKYGBge3J9Cm51IDwtIG4tMQpyYW5nZSA8LSBzZXEoLTQsIDQsIDAuMDgpICN1bmJvdW5kZWQgCnByaW50KHN0cl9jKCJkZiA9ICIsIG51KSkKcnQoMTAsIG51KQp0IDwtIHRpYmJsZSh4ID0gcmFuZ2UsIAogICAgICAgICAgICAgICAgZCA9IGR0KHgsIG51KSwKICAgICAgICAgICAgICAgIHAgPSBwdCh4LCBudSkpCnQKZ2dwbG90KHQpICsgZ2VvbV9saW5lKGFlcyh4ID0geCwgeSA9IHApKQpnZ3Bsb3QodCkgKyBnZW9tX2xpbmUoYWVzKHggPSB4LCB5ID0gZCkpCmBgYAojIyNTYW1wbGUKVXNlIG5vcm1hbAoKIyMjI2MuaS4gQ29uZmlkZW5jZSBpbnRlcnZhbApgYGB7cn0KYWxwaGEgPC0gMC4wNQpzdHJfYygiYWxwaGEgPSAiLCBhbHBoYSkKCiNDb25maWRlbmNlIGludGVydmFsCkNJIDwtIGMoc2FtcGxlX21lYW4gLSBxdCgxLWFscGhhLzIsIG51KSplc3Rfc2RfWF9iYXIsIAogICAgICAgIHNhbXBsZV9tZWFuICsgcXQoMS1hbHBoYS8yLCBudSkqZXN0X3NkX1hfYmFyKQpzdHJfYygiQ0kgPSAiLCBwYXN0ZShyb3VuZChDSSw2KSwgY29sbGFwc2UgPSAiLCAiKSkKYGBgCiMjIyNjLmlpIENvbmZpZGVuY2UgaW50ZXJ2YWwgZm9yIGRpZmZlcmVuY2Ugb2YgbWVhbnMKYGBge3J9Cm51XzIgPC0gbiArIG5fMiAtIDIKCkNJIDwtIGMoc2FtcGxlX21lYW5fZGlmZiAtIHF0KDEtYWxwaGEvMiwgbnVfMikqc2FtcGxlX3NkX3Bvb2xlZCpzcXJ0KDEvbisxL25fMiksIAogICAgICAgIHNhbXBsZV9tZWFuX2RpZmYgKyBxdCgxLWFscGhhLzIsIG51XzIpKnNhbXBsZV9zZF9wb29sZWQqc3FydCgxL24rMS9uXzIpKQoKc3RyX2MoIkNJID0gIiwgcGFzdGUocm91bmQoQ0ksNiksIGNvbGxhcHNlID0gIiwgIikpCmBgYAoKIyMjI2QuIEh5cG90aGVzaXMgdGVzdApgYGB7cn0KbXVfMCA9IDAKY3JpdGljYWxfdmFsdWVzIDwtIGMobXVfMCAtIHF0KDEtYWxwaGEvMiwgbnUpKmVzdF9zZF9YX2JhciwKICAgICAgICAgICAgICAgICAgICAgbXVfMCArIHF0KDEtYWxwaGEvMiwgbnUpKmVzdF9zZF9YX2JhcikKdCA8LSAoc2FtcGxlX21lYW4tbXVfMCkvZXN0X3NkX1hfYmFyCnN0YW5kYXJkX2NyaXRpY2FsX3ZhbHVlcyA8LSBjKHF0KGFscGhhLzIsIG51KSwgcXQoMS1hbHBoYS8yLCBudSkpCgpwX3ZhbHVlIDwtIDIqKDEtcHQoYWJzKHQpLCBudSkpCnN0cl9jKCJIMDogbXVfMCA9ICIsIG11XzApCnN0cl9jKCJkZiA9ICIsIGxlbmd0aCh4KS0xKQpzdHJfYygiY3JpdGljYWwgdmFsdWVzID0gIiwgcGFzdGUocm91bmQoY3JpdGljYWxfdmFsdWVzLDMpLGNvbGxhcHNlID0gIiwgIikpCnN0cl9jKCJzYW1wbGVfbWVhbiA9ICIsIHJvdW5kKHNhbXBsZV9tZWFuLDMpKQpzdHJfYygic3RhbmRhcmQgY3JpdGljYWwgdmFsdWVzID0gIiwgcGFzdGUocm91bmQoc3RhbmRhcmRfY3JpdGljYWxfdmFsdWVzLDMpLGNvbGxhcHNlID0gIiwgIikpCnN0cl9jKCJ0ID0gIiwgcm91bmQodCwgNCkpCnN0cl9jKCJwX3ZhbHVlID0gIiwgcm91bmQocF92YWx1ZSwgNSkpCgp0LnRlc3QoeCwgbXUgPSBtdV8wLCBzaWdtYS54ID0gc2FtcGxlX3NkKQpgYGAKCiMjQ0hJLVNRVUFSRUQKYGBge3J9CnIgPC0gNgpyYW5nZSA8LSBzZXEoMC4wMDAxLCA1KnIsIHIvMjApICN4ID4gMApwcmludChzdHJfYygiZGVncmVlcyBvZiBmcmVlZG9tID0gIiwgciwgIiwgbWVhbiA9ICIsIHIsICIsIHZhcmlhbmNlID0gIiwgMipyKSkKcmNoaXNxKDEwLCByKQpjaGlzcSA8LSB0aWJibGUoeCA9IHJhbmdlLCAKICAgICAgICAgICAgICAgIGQgPSBkY2hpc3EoeCwgciksCiAgICAgICAgICAgICAgICBwID0gcGNoaXNxKHgsIHIpKQpjaGlzcQpnZ3Bsb3QoY2hpc3EpICsgZ2VvbV9saW5lKGFlcyh4ID0geCwgeSA9IHApKQpnZ3Bsb3QoY2hpc3EpICsgZ2VvbV9saW5lKGFlcyh4ID0geCwgeSA9IGQpKQpgYGAKIyMjR29vZG5lc3Mgb2YgZml0CiMjIyNkaXNjcmV0ZSB1bmlmb3JtCmBgYHtyfQptXyA8LSAxCm4gPC0gNwpPIDwtIGMoMTcsMTAsMTIsMTUsNSw0LDgpCm4gPC0gc3VtKE8pCnggPC0gMTpsZW5ndGgoTykKbSA8LSAxLyhuLW1fKzEpCmdvZiA8LSB0aWJibGUoeCA9IHgsCiAgICAgICAgICAgICAgICBtID0gbSwKICAgICAgICAgICAgICAgIE8gPSBPLCAKICAgICAgICAgICAgICAgIEUgPSBtKm4sCiAgICAgICAgICAgICAgICAnKE8tRSleMi9FJyA9IChPLUUpXjIvRSkKZ29mCngyIDwtIHN1bShnb2YkYChPLUUpXjIvRWApCm5fcGFyYW1ldGVycyA8LSAwCnIgPC0gbnJvdyhnb2YpIC0gbl9wYXJhbWV0ZXJzIC0gMSAjayAtIHAgLSAxCnN0cl9jKCJuID0gIiwgbiwgIiwgY2hpX3NxdWFyZSA9ICIsIHJvdW5kKHgyLDMpLCAiLCBwID0gIiwgcm91bmQoMS1wY2hpc3EoeDIsIHIpLDMpKQpgYGAKIyMjI2dlb21ldHJpYwpgYGB7cn0KcF9oYXQgPC0gMC42NTcKTyA8LSBjKDcxLDI4LDEwKQpuIDwtIHN1bShPKQp4IDwtIDE6KGxlbmd0aChPKS0xKQp5IDwtIHN0cl9jKCLiiaUiLCAobGVuZ3RoKE8pKSkKbSA8LSBjKGRnKHgsIHBfaGF0KSwxLXBnKG1heCh4KSwgcF9oYXQpKQpnb2YgPC0gdGliYmxlKHggPSBjKHgseSksCiAgICAgICAgICAgICAgICBtID0gbSwKICAgICAgICAgICAgICAgIE8gPSBPLCAKICAgICAgICAgICAgICAgIEUgPSBtKm4sCiAgICAgICAgICAgICAgICAnKE8tRSleMi9FJyA9IChPLUUpXjIvRSkKZ29mCngyIDwtIHN1bShnb2YkYChPLUUpXjIvRWApCm5fcGFyYW1ldGVycyA8LSAxCnIgPC0gbnJvdyhnb2YpIC0gbl9wYXJhbWV0ZXJzIC0gMSAjayAtIHAgLSAxCnN0cl9jKCJuID0gIiwgbiwgIiwgcF9oYXQgPSAiLCBwX2hhdCwgIiwgZGYgPSAiLCByLCAiICwgY2hpX3NxdWFyZSA9ICIsIHJvdW5kKHgyLDMpLCAiLCBwID0gIiwgcm91bmQoMS1wY2hpc3EoeDIsIHIpLDMpKQpgYGAKIyMjI1BvaXNzb24KYGBge3J9CmxfaGF0IDwtIDAuNwpPIDwtIGMoMTQ0LDkxLDMyLDEzKQpuIDwtIHN1bShPKQp4IDwtIDA6KGxlbmd0aChPKS0yKQp5IDwtIHN0cl9jKCLiiaUiLCAobGVuZ3RoKE8pLTEpKQptIDwtIGMoZHBvaXMoeCwgbF9oYXQpLDEtcHBvaXMobWF4KHgpLCBsX2hhdCkpCmdvZiA8LSB0aWJibGUoeCA9IGMoeCx5KSwKICAgICAgICAgICAgICAgIG0gPSBtLAogICAgICAgICAgICAgICAgTyA9IE8sIAogICAgICAgICAgICAgICAgRSA9IG0qbiwKICAgICAgICAgICAgICAgICcoTy1FKV4yL0UnID0gKE8tRSleMi9FKQpnb2YKeDIgPC0gc3VtKGdvZiRgKE8tRSleMi9FYCkKCm5fcGFyYW1ldGVycyA8LSAxICNlc3RpbWF0ZWQgZnJvbSBkYXRhCnIgPC0gbnJvdyhnb2YpIC0gbl9wYXJhbWV0ZXJzIC0gMSAjayAtIHAgLSAxCgpzdHJfYygibiA9ICIsIG4sICIsIGxfaGF0ID0gIiwgbF9oYXQsICIsIGRmID0gIiwgciwgIiwgY2hpX3NxdWFyZSA9ICIsIHJvdW5kKHgyLDMpLCAiLCBwID0gIiwgcm91bmQoMS1wY2hpc3EoeDIsIHIpLDMpKQpgYGAKCiMjUkVHUkVTU0lPTgojIyNQb3B1bGF0aW9uCmBgYHtyfQojUGFyYW1ldGVycwpzaWdtYV9zcXVhcmVkIDwtIDE1MApzaWdtYSA8LSBzcXJ0KHNpZ21hX3NxdWFyZWQpCmFscGhhXyA8LSA1CmJldGEgPC0gNAp4IDwtIHNlcSgtNSwyMCwwLjI1KQoKaCA8LSBmdW5jdGlvbih4LCBhbHBoYV8sIGJldGEpewogICAgICAgIGFscGhhXyArIGJldGEqeAp9CiNwLmQuZi4KcmVncmVzc2lvbl9tb2RlbCA8LSB0aWJibGUoeCA9IHgsCiAgICAgICAgICAgICAgICAgcV8wLjAyNSA9IHFub3JtKDAuMDI1LCBoKHgsIGFscGhhXywgYmV0YSksIHNpZ21hKSwKICAgICAgICAgICAgICAgICBxXzAuNSA9IHFub3JtKDAuNSwgaCh4LCBhbHBoYV8sIGJldGEpLCBzaWdtYSksCiAgICAgICAgICAgICAgICAgcV8wLjk3NSA9IHFub3JtKDAuOTc1LCBoKHgsIGFscGhhXywgYmV0YSksIHNpZ21hKQogICAgICAgICAgICAgICAgICkgJT4lCiAgICAgICAgZ2F0aGVyKGtleSA9IHF1YW50aWxlLCB2YWx1ZSA9IHosIC14KQoKcmVncmVzc2lvbl9tb2RlbApnZ3Bsb3QocmVncmVzc2lvbl9tb2RlbCkgKyBnZW9tX2xpbmUoYWVzKHggPSB4LCB5ID0geiwgY29sID0gcXVhbnRpbGUpKQpgYGAKIyMjI1NhbXBsaW5nIGRpc3RyaWJ1dGlvbiBvZiB0aGUgZXN0aW1hdG9ycywgZXhwZWN0ZWQgdmFsdWVzCmBgYHtyfQpuIDwtIDUwCgpleHBfYWxwaGFfaGF0IDwtIGFscGhhCmV4cF9iZXRhX2hhdCA8LSBiZXRhCmBgYAojIyNTYW1wbGUKYGBge3J9CnJlZ3Jlc3Npb25fc2FtcGxlIDwtIHRpYmJsZSh4ID0gcnVuaWYobiwgbWluKHgpLCBtYXgoeCkpLAogICAgICAgICAgICAgICAgICAgICB5ID0gcm5vcm0oeCwgaCh4LCBhbHBoYV8sIGJldGEpLCBzaWdtYSkpCgpnZ3Bsb3QocmVncmVzc2lvbl9zYW1wbGUpICsgZ2VvbV9wb2ludChhZXMoeCA9IHgsIHkgPSB5KSkgKyBleHBhbmRfbGltaXRzKHggPSAwLCB5ID0gMCkKYGBgCiMjIyNhLiBFc3RpbWF0ZXMKYGBge3J9CnggPC0gcmVncmVzc2lvbl9zYW1wbGUkeAp4X2JhciA8LSBtZWFuKHgpCnkgPC0gcmVncmVzc2lvbl9zYW1wbGUkeQoKU194eCA8LSBzdW0oKHgtbWVhbih4KSleMikKU195eSA8LSBzdW0oKHktbWVhbih5KSleMikKU194eSA8LSBzdW0oKHgtbWVhbih4KSkqKHktbWVhbih5KSkpCgojTGVhc3Qgc3F1YXJlcyBlc3RpbWF0ZXMgb2YgcGFyYW1ldGVycwpiZXRhX2hhdCA8LSBTX3h5L1NfeHgKI2VzdF92YXJfYmV0YV9oYXQgPC0gc2lnbWFfc3F1YXJlZC9TX3h4CgphbHBoYV9oYXQgPC0gbWVhbih5KSAtIGJldGFfaGF0Km1lYW4oeCkKI2VzdF92YXJfYWxwaGFfaGF0IDwtIHhfYmFyXjIvU194eCsxL24KCiNCZXN0IGZpdApiZXN0X2ZpdCA8LSBmdW5jdGlvbih4LCBhbHBoYV9oYXQsIGJldGFfaGF0KXsKICAgICAgICBhbHBoYV9oYXQgKyBiZXRhX2hhdCp4Cn0KCnJlZ3Jlc3Npb25fc2FtcGxlIDwtIHJlZ3Jlc3Npb25fc2FtcGxlICU+JSAKICAgICAgICBtdXRhdGUoeV9oYXQgPSBiZXN0X2ZpdCh4LCBhbHBoYV9oYXQsIGJldGFfaGF0KSwKICAgICAgICAgICAgICAgcmVzaWR1YWwgPSB5LXlfaGF0ICkKCiNWYXJpYW5jZSBvZiByZXNpZHVhbHMKeV9oYXQgPC0gcmVncmVzc2lvbl9zYW1wbGUkeV9oYXQKc3VtX3NxdWFyZWRfZGlmZl95X2hhdCA8LSBzdW0oKHkteV9oYXQpXjIpCgpzX3NxdWFyZWQgPC0gc3VtX3NxdWFyZWRfZGlmZl95X2hhdC8obi0yKSAjdW5iaWFzZWQgZXN0aW1hdG9yIG9mIHNpZ21hX3NxdWFyZWQsIHRoZSB2YXJpYW5jZSBvZiB0aGUgcmFuZG9tIHRlcm1zCnMgPC0gc3FydChzX3NxdWFyZWQpCgplc3Rfc2RfYmV0YV9oYXQgPC0gcy9zcXJ0KFNfeHgpCgpnZ3Bsb3QocmVncmVzc2lvbl9zYW1wbGUpICsgZ2VvbV9wb2ludChhZXMoeCA9IHgsIHkgPSB5KSkgKyBnZW9tX2xpbmUoYWVzKHggPSB4LCB5ID0geV9oYXQpKQpgYGAKIyMjI2MuaS4gQ29uZmlkZW5jZSBpbnRlcnZhbCBmb3IgYmV0YQpgYGB7cn0KYWxwaGEgPC0gMC4wNQoKQ0lfYmV0YSA8LSBjKAogICAgICAgIGJldGFfaGF0IC0gcXQoMS1hbHBoYS8yLCBuLTIpKmVzdF9zZF9iZXRhX2hhdCwgCiAgICAgICAgYmV0YV9oYXQgKyBxdCgxLWFscGhhLzIsIG4tMikqZXN0X3NkX2JldGFfaGF0KQoKc3RyX2MoImJldGFfaGF0ID0gIiwgcm91bmQoYmV0YV9oYXQsMyksICIsIENJX2JldGEgPSAiLCBwYXN0ZShyb3VuZChDSV9iZXRhLDMpLCBjb2xsYXBzZSA9ICIsICIpKQpgYGAKIyMjI2MuaWkuIENvbmZpZGVuY2UgaW50ZXJ2YWwgZm9yIG1lYW4gcmVzcG9uc2UKYGBge3J9CmVzdF9zZF9ZX2JhciA8LSBmdW5jdGlvbih4LCBzLCB4X2JhciwgU194eCwgbil7CiAgICAgICAgcypzcXJ0KCh4LXhfYmFyKV4yL1NfeHggKyAxL24pCn0KICAgICAgICAKcmVncmVzc2lvbl9zYW1wbGUgPC0gcmVncmVzc2lvbl9zYW1wbGUgJT4lIAogbXV0YXRlKENJX2xvdyA9IHlfaGF0IC0gcXQoMS1hbHBoYS8yLCBuLTIpKmVzdF9zZF9ZX2Jhcih4LCBzLCB4X2JhciwgU194eCwgbiksCiAgICAgICAgQ0lfaGlnaCA9IHlfaGF0ICsgcXQoMS1hbHBoYS8yLCBuLTIpKmVzdF9zZF9ZX2Jhcih4LCBzLCB4X2JhciwgU194eCwgbikpCgpnZ3Bsb3QocmVncmVzc2lvbl9zYW1wbGUpICsgZ2VvbV9wb2ludChhZXMoeCA9IHgsIHkgPSB5KSkgKyBnZW9tX2xpbmUoYWVzKHggPSB4LCB5ID0geV9oYXQpKSArIGdlb21fbGluZShhZXMoeCA9IHgsIHkgPSBDSV9sb3cpKSArIGdlb21fbGluZShhZXMoeCA9IHgsIHkgPSBDSV9oaWdoKSkKYGBgCgojIyMjYy5paWkuIFByZWRpY3Rpb24gaW50ZXJ2YWwKYGBge3J9CmVzdF9zZF9ZIDwtIGZ1bmN0aW9uKHgsIHMsIHhfYmFyLCBTX3h4LCBuKXsKICAgICAgICBzKnNxcnQoKHgteF9iYXIpXjIvU194eCArIDEvbiArIDEpCn0KICAgICAgICAKcmVncmVzc2lvbl9zYW1wbGUgPC0gcmVncmVzc2lvbl9zYW1wbGUgJT4lIAogbXV0YXRlKENJX2xvdyA9IHlfaGF0IC0gcXQoMS1hbHBoYS8yLCBuLTIpKmVzdF9zZF9ZKHgsIHMsIHhfYmFyLCBTX3h4LCBuKSwKICAgICAgICBDSV9oaWdoID0geV9oYXQgKyBxdCgxLWFscGhhLzIsIG4tMikqZXN0X3NkX1koeCwgcywgeF9iYXIsIFNfeHgsIG4pKQoKZ2dwbG90KHJlZ3Jlc3Npb25fc2FtcGxlKSArIGdlb21fcG9pbnQoYWVzKHggPSB4LCB5ID0geSkpICsgZ2VvbV9saW5lKGFlcyh4ID0geCwgeSA9IHlfaGF0KSkgKyBnZW9tX2xpbmUoYWVzKHggPSB4LCB5ID0gQ0lfbG93KSkgKyBnZW9tX2xpbmUoYWVzKHggPSB4LCB5ID0gQ0lfaGlnaCkpCmBgYAojIyMjZC4gSHlwb3RoZXNpcyB0ZXN0IGZvciBiZXRhCmBgYHtyfQpiZXRhXzAgPSAwCmNyaXRpY2FsX3ZhbHVlcyA8LSBjKGJldGFfMCAtIHF0KDEtYWxwaGEvMiwgbi0yKSplc3Rfc2RfYmV0YV9oYXQsCiAgICAgICAgICAgICAgICAgICAgIGJldGFfMCArIHF0KDEtYWxwaGEvMiwgbi0yKSplc3Rfc2RfYmV0YV9oYXQpCnQgPC0gKGJldGFfaGF0LWJldGFfMCkvZXN0X3NkX2JldGFfaGF0CnN0YW5kYXJkX2NyaXRpY2FsX3ZhbHVlcyA8LSBjKHF0KGFscGhhLzIsIG4tMiksIHF0KDEtYWxwaGEvMiwgbi0yKSkKCnBfdmFsdWUgPC0gMiooMS1wdChhYnModCksIG4tMikpCmBgYAoKIyNOT04tUEFSQU1FVFJJQwojIyNXaWxrb3hvbiBzaWduZWQgcmFuawpgYGB7cn0KI1NpbmdsZSBzYW1wbGUKeCA8LSBjKDE5LCAzNSwgMzYsIDI4LCAzNywgMTAsIDI1LCAzNCwgMzAsIDM5KQptXzAgPSAzNSAjc2V0IGh5cG90aGVzaXplZCBtZWRpYW4KZF8gPC0geC1tXzAgI2NhbGN1bGF0ZSBkaWZmZXJlbmNlCgojc2V0IG9mIHBhaXJlZCBkaWZmZXJlbmNlcwp4MSA8LSBjKDE3MSwgNzI5LCA2NzksIDQzMSwgMzAwLCAzMTAsIDc5NCwgOTcwLCAzODgpCngyIDwtIGMoMTk4LCA3MzQsIDc3OSwgNzc2LCAzMDAsIDc1MCwgNjk3LCAzNjgsIDQ4OCkKZF8gPC0geDEteDIKCmQgPC0gZF9bZF8hPTBdICNyZW1vdmUgemVyb3MKcmFuayA8LSByYW5rKGFicyhkKSkgI2ZpbmQgdGhlIHJhbmsgb2YgYWJzb2x1dGUgdmFsdWVzCndfcGx1cyA8LSBzdW0ocmFua1tzaWduKGQpPT0xXSkgI3N1bSBvZiB0aGUgcmFua3Mgb2YgcG9zaXRpdmUgZGlmZmVyZW5jZXMKd19wbHVzCndpbGNveC50ZXN0KGQpCmBgYApOb3JtYWwgYXBwcm94aW1hdGlvbgpgYGB7cn0KI25vcm1hbCBhcHByb3hpbWF0aW9uIHdoZW4gbiDiiaUgMTYKbiA8LSBsZW5ndGgoZCkKCmV4cF93X3BsdXMgPC0gKG4qKG4rMSkpLzQKdmFyX3dfcGx1cyA8LSAobioobisxKSooMipuKzEpKS8yNApzZF93X3BsdXMgPC0gc3FydCh2YXJfd19wbHVzKQoKYWxwaGEgPC0gMC4wNQpjcml0aWNhbF92YWx1ZXMgPC0gYyhtXzAgLSBxbm9ybSgxLWFscGhhLzIpKnNkX3dfcGx1cywKICAgICAgICAgICAgICAgICAgICAgbV8wICsgcW5vcm0oMS1hbHBoYS8yKSpzZF93X3BsdXMpCnogPC0gKHdfcGx1cyAtIGV4cF93X3BsdXMpL3NkX3dfcGx1cwpzdGFuZGFyZF9jcml0aWNhbF92YWx1ZXMgPC0gYyhxbm9ybShhbHBoYS8yKSwgcW5vcm0oMS1hbHBoYS8yKSkKcF92YWx1ZSA8LSAyKigxLXBub3JtKGFicyh6KSkpCgpzdHJfYygibiA9ICIsIG4pCnN0cl9jKCJIMDogbV8wID0gIiwgbV8wKQpzdHJfYygiY3JpdGljYWwgdmFsdWVzID0gIiwgcGFzdGUocm91bmQoY3JpdGljYWxfdmFsdWVzLDMpLGNvbGxhcHNlID0gIiwgIikpCnN0cl9jKCJleHBfd19wbHVzID0gIiwgZXhwX3dfcGx1cykKc3RyX2MoInN0YW5kYXJkIGNyaXRpY2FsIHZhbHVlcyA9ICIsIHBhc3RlKHJvdW5kKHN0YW5kYXJkX2NyaXRpY2FsX3ZhbHVlcywzKSxjb2xsYXBzZSA9ICIsICIpKQpzdHJfYygieiA9ICIsIHJvdW5kKHosIDMpKQpzdHJfYygicF92YWx1ZSA9ICIsIHJvdW5kKHBfdmFsdWUsIDUpKQpgYGAKCiMjI01hbm4tV2hpdG5leQpgYGB7cn0KYSA9IGMoMTAxLDEwNCwxMDcsMTA3LDEyMSwxMjEsMTI0LDEzNCwxNDYpIApiID0gYyg5MSw5Myw5NywxMDAsMTAxLDEwMiwxMDcsMTE0LDExNSwxMjYsMTMxKQoKdV9hIDwtIHN1bShyYW5rKGMoYSxiKSlbMTpsZW5ndGgoYSldKQp1X2EKYGBgCgpOb3JtYWwgYXBwcm94aW1hdGlvbgpgYGB7cn0KI25vcm1hbCBhcHByb3hpbWF0aW9uIHdoZW4gZWFjaCBzYW1wbGUg4omlIDgKbl9hIDwtIGxlbmd0aChhKQpuX2IgPC0gbGVuZ3RoKGIpCgpleHBfdV9hIDwtIChuX2EqKG5fYStuX2IrMSkpLzIKdmFyX3VfYSA8LSAobl9hKm5fYioobl9hK25fYisxKSkvMTIKc2RfdV9hIDwtIHNxcnQodmFyX3VfYSkKCmFscGhhIDwtIDAuMDUKY3JpdGljYWxfdmFsdWVzIDwtIGMobV8wIC0gcW5vcm0oMS1hbHBoYS8yKSpzZF91X2EsCiAgICAgICAgICAgICAgICAgICAgIG1fMCArIHFub3JtKDEtYWxwaGEvMikqc2RfdV9hKQp6IDwtICh1X2EgLSBleHBfdV9hKS9zZF91X2EKc3RhbmRhcmRfY3JpdGljYWxfdmFsdWVzIDwtIGMocW5vcm0oYWxwaGEvMiksIHFub3JtKDEtYWxwaGEvMikpCnBfdmFsdWUgPC0gMiooMS1wbm9ybShhYnMoeikpKQoKc3RyX2MoIm5fYSA9ICIsIG5fYSwgIiwgbl9iID0gIiwgbl9iKQpzdHJfYygiSDA6IG1fMCA9ICIsIG1fMCkKc3RyX2MoImNyaXRpY2FsIHZhbHVlcyA9ICIsIHBhc3RlKHJvdW5kKGNyaXRpY2FsX3ZhbHVlcywzKSxjb2xsYXBzZSA9ICIsICIpKQpzdHJfYygiZXhwX3VfYSA9ICIsIGV4cF91X2EpCnN0cl9jKCJzdGFuZGFyZCBjcml0aWNhbCB2YWx1ZXMgPSAiLCBwYXN0ZShyb3VuZChzdGFuZGFyZF9jcml0aWNhbF92YWx1ZXMsMyksY29sbGFwc2UgPSAiLCAiKSkKc3RyX2MoInogPSAiLCByb3VuZCh6LCAzKSkKc3RyX2MoInBfdmFsdWUgPSAiLCByb3VuZChwX3ZhbHVlLCA1KSkKYGBgCiMjTk9URVMKIyNUbyBkbwpOb24tbGluZWFyIHJlZ3Jlc3Npb24gbW9kZWxzIGFuZCB0cmFuc2Zvcm1hdGlvbnMKQ2hpLXNxdWFyZSBnb29kbmVzcyBvZiBmaXQgdGVzdCBmb3IgYmlub21pYWwKCiMjI05vcm1hbCBwcm9iYWJpbGl0eSBwbG90CmBgYHtyfQpPIDwtIGMoMzMsIDIsIDI0LCAyNywgNCwgMSwgLTYpCnggPC0gc29ydChPKQpuIDwtIGxlbmd0aCh4KQppIDwtIDE6bgpwIDwtIGkvKG4rMSkKeSA8LSBxbm9ybShwKQpxcGxvdCh4LHkpICsgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIiwgc2UgPSBGQUxTRSkKCmBgYAojIyNDZW50cmFsIGxpbWl0IHRoZW9yZW0KYGBge3J9CiNuIDwtIDEwCm5fdHJpYWxzIDwtIDUwMAp4IDwtIGMoKQpmb3IgKGkgaW4gMTpuX3RyaWFscykgewogICAgICAgIHhbaV0gPC0gbWVhbihyYmVybm91bGxpKG5fdHJpYWxzLDAuMDAxKSkgICAgICAgIAp9CgojZ2dwbG90KCkgKyBzdGF0X3FxX2xpbmUoYWVzKHNhbXBsZSA9IHgpKSArIHN0YXRfcXEoYWVzKHNhbXBsZSA9IHgpKQpnZ3Bsb3QoKSArIGdlb21faGlzdG9ncmFtKGFlcyh4ID0geCksIGJpbndpZHRoID0gMC4wMDAwMikKYGBgCiMjI0xhZGRlciBvZiBwb3dlcnMKYGBge3J9CmRmIDwtIHRpYmJsZSh4ID0gcm5vcm0oMTAsIDEwMCwgMTApLCB5ID0geCArIHJub3JtKDEwLCAwLCAxKSkKZGYKZ2dwbG90KGRmKSArIGdlb21fcG9pbnQoYWVzKHggPSB4LCB5ID0geSkpCmBgYAojIyNCaW5vbWlhbCB2cyBQb2lzc29uCmBgYHtyfQp4IDwtIGJpbm9tICU+JSBzZWxlY3QoeCwgQmlub21pYWwgPSBkKQp5IDwtIHBvaXNzb24gJT4lIHNlbGVjdCh4LCBQb2lzc29uID0gZCkgJT4lIGxlZnRfam9pbih4LCBieSA9ICJ4IikKeiA8LSB5ICU+JSBnYXRoZXIoa2V5LCB2YWx1ZSA9IGQsIC14KQpnZ3Bsb3QoeikgKyBnZW9tX3BvaW50KGFlcyh4ID0geCwgeSA9IGQsIGNvbCA9IGtleSkpCmBgYAoKCiMjI1N0YXRpc3RpY2FsIHRhYmxlcwpgYGB7cn0KeCA8LSAwOjkvMTAwCnBoaV90YWJsZSA8LSB0aWJibGUoeiA9IHNlcSgwLDQsMC4xKSwgCiAgICAgICAnMCcgPSByb3VuZChwbm9ybSh6K3hbMV0pLDQpLAogICAgICAgJzEnID0gcm91bmQocG5vcm0oeit4WzJdKSw0KSwKICAgICAgICcyJyA9IHJvdW5kKHBub3JtKHoreFszXSksNCksCiAgICAgICAnMycgPSByb3VuZChwbm9ybSh6K3hbNF0pLDQpLAogICAgICAgJzQnID0gcm91bmQocG5vcm0oeit4WzVdKSw0KSwKICAgICAgICc1JyA9IHJvdW5kKHBub3JtKHoreFs2XSksNCksCiAgICAgICAnNicgPSByb3VuZChwbm9ybSh6K3hbN10pLDQpLAogICAgICAgJzcnID0gcm91bmQocG5vcm0oeit4WzhdKSw0KSwKICAgICAgICc4JyA9IHJvdW5kKHBub3JtKHoreFs5XSksNCksCiAgICAgICAnOScgPSByb3VuZChwbm9ybSh6K3hbMTBdKSw0KQogICAgICAgKQpwaGlfdGFibGUKYGBgCmBgYHtyfQpxel90YWJsZSA8LSB0aWJibGUoYSA9IHNlcSgwLjUsMC45OTksMC4wMSksIHFfYSA9IHJvdW5kKHFub3JtKGEpLDMpKQpxel90YWJsZQpgYGAKCmBgYHtyfQpxdF90YWJsZSA8LSB0aWJibGUoZGYgPSAxOjEwMCwgCiAgICAgICAgICAgICAgICAgICAnMC45MCcgPSByb3VuZChxdCgwLjksIGRmKSwzKSwKICAgICAgICAgICAgICAgICAgICcwLjk1JyA9IHJvdW5kKHF0KDAuOTUsIGRmKSwzKSwKICAgICAgICAgICAgICAgICAgICcwLjk3NScgPSByb3VuZChxdCgwLjk3NSwgZGYpLDMpLAogICAgICAgICAgICAgICAgICAgJzAuOTknID0gcm91bmQocXQoMC45OSwgZGYpLDMpLAogICAgICAgICAgICAgICAgICAgJzAuOTk1JyA9IHJvdW5kKHF0KDAuOTk1LCBkZiksMyksCiAgICAgICAgICAgICAgICAgICAnMC45OTknID0gcm91bmQocXQoMC45OTksIGRmKSwzKSkKcXRfdGFibGUKYGBgCgpgYGB7cn0KY2hpc3FfdGFibGUgPC0gdGliYmxlKGRmID0gMToxMDAsIAogICAgICAgICAgICAgICAgICAgJzAuMDA1JyA9IHJvdW5kKHFjaGlzcSgwLjAwNSwgZGYpLDIpLAogICAgICAgICAgICAgICAgICAgJzAuMDEnID0gcm91bmQocWNoaXNxKDAuMDEsIGRmKSwyKSwKICAgICAgICAgICAgICAgICAgICcwLjAyNScgPSByb3VuZChxY2hpc3EoMC4wMjUsIGRmKSwyKSwKICAgICAgICAgICAgICAgICAgICcwLjA1JyA9IHJvdW5kKHFjaGlzcSgwLjA1LCBkZiksMiksCiAgICAgICAgICAgICAgICAgICAnMC4xJyA9IHJvdW5kKHFjaGlzcSgwLjEsIGRmKSwyKSwKICAgICAgICAgICAgICAgICAgICcwLjUnID0gcm91bmQocWNoaXNxKDAuNSwgZGYpLDIpLAogICAgICAgICAgICAgICAgICAgJzAuOScgPSByb3VuZChxY2hpc3EoMC45LCBkZiksMiksCiAgICAgICAgICAgICAgICAgICAnMC45NScgPSByb3VuZChxY2hpc3EoMC45NSwgZGYpLDIpLAogICAgICAgICAgICAgICAgICAgJzAuOTc1JyA9IHJvdW5kKHFjaGlzcSgwLjk3NSwgZGYpLDIpLAogICAgICAgICAgICAgICAgICAgJzAuOTknID0gcm91bmQocWNoaXNxKDAuOTksIGRmKSwyKSwKICAgICAgICAgICAgICAgICAgICcwLjk5NScgPSByb3VuZChxY2hpc3EoMC45OTUsIGRmKSwyKSkKY2hpc3FfdGFibGUKYGBgCgpQb2lzc29uIHZzIGdlb21ldHJpYwpgYGB7cn0KcCA8LSAwLjcKbCA8LSAwLjUgI2dlbmVyYWxseSBzdGVlcGVyIHRoYW4gZ2VvbWV0cmljLCBnZXRzIGEgYnVtcCBhcyBhcHByb2FjaGVzIGwgPSAxCmRmIDwtIHRpYmJsZSh4ID0gMDo5LCBHZW9tZXRyaWMgPSByb3VuZChkZ2VvbSh4LCBwKSwgNCksIFBvaXNzb24gPSByb3VuZChkcG9pcyh4LCBsKSwgNCkpICU+JSBnYXRoZXIoa2V5LCB2YWx1ZSwgLXgpCmdncGxvdChkZikgKyBnZW9tX3BvaW50KGFlcyh4ID0geCwgeSA9IHZhbHVlLCBjb2wgPSAga2V5KSkKYGBgCgpCaW5vbWlhbCBhbHRlcm5hdGl2ZSBNTEU/CmBgYHtyfQojIE1MRSBtdWx0aXBsZSBvYnNlcnZhdGlvbnMKIyB4IDwtIHJiaW5vbSgxMCwgbiwgcCkKIyB4CiMgdGhldGEgPC0gc2VxKDAsMSwwLjAwMSkKIyBtIDwtIE5VTEwKIyBmb3IoaSBpbiAxOmxlbmd0aCh0aGV0YSkpewojICAgICAgICAgbVtpXSA8LSAgcHJvZChkKHgsIG4sIHRoZXRhW2ldKSkKIyB9CiMgYmlub21fbWxlMiA8LSB0aWJibGUodGhldGEgPSB0aGV0YSwgbSA9IG0pCiMgTUxFMiA8LSBmaWx0ZXIoYmlub21fbWxlMiwgbSA9PSBtYXgobSkpJHRoZXRhCiMgcHJpbnQoc3RyX2MoIk1MRTIgPSAiLCBNTEUyKSkKIyBtZWFuKHJhbmQpL24KIyBnZ3Bsb3QoYmlub21fbWxlMikgKyBnZW9tX2xpbmUoYWVzKHggPSB0aGV0YSwgeSA9IG0pKQoKYGBgCgo=